"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const module_cfg_loader_1 = require("../../modules/module.cfg-loader");
const crunchyroll_1 = __importDefault(require("./services/crunchyroll"));
const hidive_1 = __importDefault(require("./services/hidive"));
const animeonegai_1 = __importDefault(require("./services/animeonegai"));
const adn_1 = __importDefault(require("./services/adn"));
const websocket_1 = __importDefault(require("./websocket"));
const package_json_1 = __importDefault(require("../../package.json"));
class ServiceHandler {
    constructor(server) {
        this.service = undefined;
        this.ws = new websocket_1.default(server);
        this.handleMessages();
        this.state = (0, module_cfg_loader_1.getState)();
    }
    handleMessages() {
        this.ws.events.on('setupServer', ({ data }, respond) => {
            (0, module_cfg_loader_1.writeYamlCfgFile)('gui', data);
            this.state.setup = true;
            (0, module_cfg_loader_1.setState)(this.state);
            respond(true);
            process.exit(0);
        });
        this.ws.events.on('setup', ({ data }) => {
            if (data === 'crunchy') {
                this.service = new crunchyroll_1.default(this.ws);
            }
            else if (data === 'hidive') {
                this.service = new hidive_1.default(this.ws);
            }
            else if (data === 'ao') {
                this.service = new animeonegai_1.default(this.ws);
            }
            else if (data === 'adn') {
                this.service = new adn_1.default(this.ws);
            }
        });
        this.ws.events.on('changeProvider', (_, respond) => __awaiter(this, void 0, void 0, function* () {
            var _a;
            if (yield ((_a = this.service) === null || _a === void 0 ? void 0 : _a.isDownloading()))
                return respond(false);
            this.service = undefined;
            respond(true);
        }));
        this.ws.events.on('auth', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            if (this.service === undefined)
                return respond({ isOk: false, reason: new Error('No service selected') });
            respond(yield this.service.auth(data));
        }));
        this.ws.events.on('version', (_, respond) => __awaiter(this, void 0, void 0, function* () {
            respond(package_json_1.default.version);
        }));
        this.ws.events.on('type', (_, respond) => __awaiter(this, void 0, void 0, function* () { return respond(this.service === undefined ? undefined : this.service.name); }));
        this.ws.events.on('checkToken', (_, respond) => __awaiter(this, void 0, void 0, function* () {
            if (this.service === undefined)
                return respond({ isOk: false, reason: new Error('No service selected') });
            respond(yield this.service.checkToken());
        }));
        this.ws.events.on('search', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            if (this.service === undefined)
                return respond({ isOk: false, reason: new Error('No service selected') });
            respond(yield this.service.search(data));
        }));
        this.ws.events.on('default', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            if (this.service === undefined)
                return respond({ isOk: false, reason: new Error('No service selected') });
            respond(yield this.service.handleDefault(data));
        }));
        this.ws.events.on('availableDubCodes', (_, respond) => __awaiter(this, void 0, void 0, function* () {
            if (this.service === undefined)
                return respond([]);
            respond(yield this.service.availableDubCodes());
        }));
        this.ws.events.on('availableSubCodes', (_, respond) => __awaiter(this, void 0, void 0, function* () {
            if (this.service === undefined)
                return respond([]);
            respond(yield this.service.availableSubCodes());
        }));
        this.ws.events.on('resolveItems', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            if (this.service === undefined)
                return respond(false);
            respond(yield this.service.resolveItems(data));
        }));
        this.ws.events.on('listEpisodes', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            if (this.service === undefined)
                return respond({ isOk: false, reason: new Error('No service selected') });
            respond(yield this.service.listEpisodes(data));
        }));
        this.ws.events.on('downloadItem', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            var _b;
            (_b = this.service) === null || _b === void 0 ? void 0 : _b.downloadItem(data);
            respond(undefined);
        }));
        this.ws.events.on('openFolder', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            var _b;
            (_b = this.service) === null || _b === void 0 ? void 0 : _b.openFolder(data);
            respond(undefined);
        }));
        this.ws.events.on('openFile', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            var _b;
            (_b = this.service) === null || _b === void 0 ? void 0 : _b.openFile(data);
            respond(undefined);
        }));
        this.ws.events.on('openURL', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            var _b;
            (_b = this.service) === null || _b === void 0 ? void 0 : _b.openURL(data);
            respond(undefined);
        }));
        this.ws.events.on('getQueue', (_, respond) => __awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            respond((_b = yield ((_a = this.service) === null || _a === void 0 ? void 0 : _a.getQueue())) !== null && _b !== void 0 ? _b : []);
        }));
        this.ws.events.on('removeFromQueue', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            var _b;
            (_b = this.service) === null || _b === void 0 ? void 0 : _b.removeFromQueue(data);
            respond(undefined);
        }));
        this.ws.events.on('clearQueue', (_, respond) => __awaiter(this, void 0, void 0, function* () {
            var _a;
            (_a = this.service) === null || _a === void 0 ? void 0 : _a.clearQueue();
            respond(undefined);
        }));
        this.ws.events.on('setDownloadQueue', (_a, respond_1) => __awaiter(this, [_a, respond_1], void 0, function* ({ data }, respond) {
            var _b;
            (_b = this.service) === null || _b === void 0 ? void 0 : _b.setDownloadQueue(data);
            respond(undefined);
        }));
        this.ws.events.on('getDownloadQueue', (_, respond) => __awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            respond((_b = yield ((_a = this.service) === null || _a === void 0 ? void 0 : _a.getDownloadQueue())) !== null && _b !== void 0 ? _b : false);
        }));
        this.ws.events.on('isDownloading', (_, respond) => __awaiter(this, void 0, void 0, function* () { var _a, _b; return respond((_b = yield ((_a = this.service) === null || _a === void 0 ? void 0 : _a.isDownloading())) !== null && _b !== void 0 ? _b : false); }));
    }
}
exports.default = ServiceHandler;
