import { GcConsole } from '../../gc-core-assets/lib/GcConsole';
import { ServiceType, ServicesRegistry } from '../../gc-core-services/lib/ServicesRegistry';
import { backplaneServiceType } from '../../gc-service-backplane/lib/BackplaneService';

/**
 *  Copyright (c) 2025 Texas Instruments Incorporated
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  *   Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  *   Neither the name of Texas Instruments Incorporated nor the names of
 *  its contributors may be used to endorse or promote products derived
 *  from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
const MODULE_NAME = 'gc-service-tcp-ip';
const console = new GcConsole(MODULE_NAME);
function isDataEvent(type) {
    return type === 'data';
}
const tcpipServiceType = new ServiceType(MODULE_NAME);
class TCPIPService {
    async createTCPClient(host, port) {
        const backplaneService = ServicesRegistry.getService(backplaneServiceType);
        const module = await backplaneService.getSubModule('TCPClient');
        const subModuleName = await module.createTCPClient(host, port);
        const subModule = await module.getSubModule(subModuleName);
        // since we are mapping two different types of listeners for data event, we need to keep track of them to be able to remove the listener as well.
        const listenerMap = new WeakMap();
        return {
            addListener: (type, listener) => {
                if (isDataEvent(type)) {
                    const internalListener = (data) => {
                        const binaryStr = atob(data);
                        const numberArray = Array.from(binaryStr, char => char.charCodeAt(0));
                        listener(numberArray);
                    };
                    listenerMap.set(listener, internalListener);
                    subModule.addListener(type, internalListener);
                }
                else {
                    subModule.addListener(type, listener);
                }
            },
            removeListener: (type, listener) => {
                if (isDataEvent(type)) {
                    const internalListener = listenerMap.get(listener);
                    if (internalListener) {
                        subModule.removeListener(type, internalListener);
                        listenerMap.delete(listener);
                    }
                }
                else {
                    subModule.removeListener(type, listener);
                }
            },
            write: async (data) => {
                if (typeof data === 'string') {
                    await subModule.write({ type: 'string', data: data });
                }
                else {
                    await subModule.write({ type: 'uint8array', data: btoa(String.fromCharCode(...data)) });
                }
            },
            disconnect: () => {
                subModule.close();
            },
            connect: async () => {
                await subModule.connect();
            }
        };
    }
}
ServicesRegistry.register(tcpipServiceType, TCPIPService);

export { MODULE_NAME, TCPIPService, tcpipServiceType };
//# sourceMappingURL=TCPIPService.js.map
