#include compat.js
#include mszauth.js
#include ui/hooks.js

const MamiSockChat = function(protoWorker) {
    const events = protoWorker.eventTarget('sockchat');
    let restarting = false;
    let client;
    let dumpPackets = false;

    return {
        get client() { return client; },

        watch: events.watch,
        unwatch: events.unwatch,

        create: async () => {
            if(client !== undefined && typeof client.close === 'function')
                // intentional fire & forget, worker may be gone, don't want to wait for it to time out
                client.close();

            restarting = false;
            client = await protoWorker.root.create('sockchat', { ping: futami.get('ping') });
            await client.setDumpPackets(dumpPackets);

            Umi.UI.Hooks.SetCallbacks(client.sendMessage, client.switchChannel);

            MamiCompat('Umi.Server', { get: () => client, configurable: true });
            MamiCompat('Umi.Server.SendMessage', { value: text => client.sendMessage(text), configurable: true });
            MamiCompat('Umi.Protocol.SockChat.Protocol.Instance.SendMessage', { value: text => client.sendMessage(text), configurable: true });
            MamiCompat('Umi.Protocol.SockLegacy.Protocol.Instance.SendMessage', { value: text => client.sendMessage(text), configurable: true });
        },
        connect: async url => {
            try {
                await client.open(url);
            } catch(ex) {
                return ex.wasKicked === true;
            }
        },
        authenticate: async () => {
            const authInfo = MamiMisuzuAuth.getInfo();
            await client.sendAuth(authInfo.method, authInfo.token);
        },
        setDumpPackets: async state => {
            dumpPackets = !!state;

            if(client !== undefined && typeof client.setDumpPackets === 'function')
                await client.setDumpPackets(dumpPackets);
        },
    };
};
