"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
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 });
exports.FactoryLocalBackend = void 0;
const express_1 = __importDefault(require("express"));
const http = __importStar(require("http"));
const express_fileupload_1 = __importDefault(require("express-fileupload"));
const path = __importStar(require("path"));
const Factory_1 = require("./Factory");
const FactoryDatabase_1 = require("./FactoryDatabase");
const fs_extra_1 = __importDefault(require("fs-extra"));
const Trial_1 = require("./Trial");
const Source_1 = require("./Source");
const ModList_1 = require("./ModList");
const DatasetAnalysis_1 = require("./DatasetAnalysis");
const FactorioApi_1 = require("./FactorioApi");
const Logging_1 = require("./Logging");
class FactoryLocalBackend {
    static cacheDataset(results, trialId, category) {
        results.cachedAt = new Date();
        FactoryLocalBackend.cachedDatasets.set(trialId + '-' + category, results);
        // we can only have up to 10 datasets cached at once - for the sake of ram usage
        // look through the cache, and remove the oldest one if we have more than 10
        // dont use foreach
        if (FactoryLocalBackend.cachedDatasets.size > 10) {
            let oldest = new Date();
            let oldestKey = '';
            for (let key of FactoryLocalBackend.cachedDatasets.keys()) {
                let d = FactoryLocalBackend.cachedDatasets.get(key).cachedAt;
                if (d < oldest) {
                    oldest = d;
                    oldestKey = key;
                }
            }
            FactoryLocalBackend.cachedDatasets.delete(oldestKey);
        }
    }
    //static sockets: Map<string, Socket> = new Map<string, Socket>()
    static startServer(port = 3001) {
        return __awaiter(this, void 0, void 0, function* () {
            Logging_1.Logging.log('info', 'Starting server on port ' + port);
            FactoryLocalBackend.app = (0, express_1.default)();
            FactoryLocalBackend.app.use(express_1.default.json());
            FactoryLocalBackend.app.use(express_1.default.urlencoded({ extended: true }));
            FactoryLocalBackend.app.use((0, express_fileupload_1.default)({
                limits: { fileSize: 500 * 1024 * 1024 },
            }));
            FactoryLocalBackend.app.use('/', express_1.default.static('public'));
            FactoryLocalBackend.app.get('/api/factoryStatus', (req, res) => {
                // what is the factory currently doing? Startup status? Running status? etc
                try {
                    res.json({
                        startupStatus: Factory_1.Factory.initStatus,
                        isTrialRunning: Factory_1.Factory.isTrialRunning,
                        isFactorioRunning: Factory_1.Factory.factorioRunning,
                        version: Factory_1.Factory.factoryVersion
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/factoryPaths', (req, res) => {
                try {
                    res.json({
                        factoryInstallPath: Factory_1.Factory.factoryInstallPath,
                        factoryDataPath: Factory_1.Factory.factoryDataPath,
                        factoryModsPath: Factory_1.Factory.modsPath,
                        factoryModsCachePath: Factory_1.Factory.modsCachePath,
                        factorySavesPath: Factory_1.Factory.savesPath,
                        factoryScenariosPath: Factory_1.Factory.scenariosPath
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/modCache', (req, res) => {
                try {
                    res.json({
                        modCache: [...Factory_1.Factory.modCache]
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.post('/upload/savegame', (req, res) => {
                let fileNames = Object.keys(req.files);
                // we just grab the first file and upload it - rest are ignored
                let file = req.files[fileNames[0]];
                file.mv(path.join(Factory_1.Factory.factoryDataPath, 'saves-upload', file.name), function (err) {
                    if (err) {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    }
                    else {
                        res.send('ok');
                    }
                });
            });
            FactoryLocalBackend.app.get('/api/listSaves', (req, res) => {
                try {
                    fs_extra_1.default.readdir(path.join(Factory_1.Factory.factoryDataPath, 'saves-upload')).then((files) => {
                        res.send(files.map((f) => {
                            return path.join(Factory_1.Factory.factoryDataPath, 'saves-upload', f);
                        }));
                    }).catch((e) => {
                        Logging_1.Logging.log('error', e);
                        res.status(501).send(e);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.post('/api/createTrial', (req, res) => {
                try {
                    let params = req.body;
                    let t = new Trial_1.Trial(params);
                    FactoryDatabase_1.FactoryDatabase.saveTrial(t).then(() => {
                        res.send(t);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.post('/api/createSource', (req, res) => {
                try {
                    let params = req.body;
                    let s = new Source_1.Source(params);
                    FactoryDatabase_1.FactoryDatabase.saveSource(s).then(() => {
                        res.send(s);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.post('/api/createModList', (req, res) => {
                try {
                    let params = req.body;
                    let m = new ModList_1.ModList(params);
                    FactoryDatabase_1.FactoryDatabase.saveModList(m).then(() => {
                        res.send(m);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.post('/api/updateTrial', (req, res) => {
                try {
                    let trial = new Trial_1.Trial(req.body);
                    FactoryDatabase_1.FactoryDatabase.saveTrial(trial, false).then((rettrial) => {
                        res.send(rettrial);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.post('/api/updateSource', (req, res) => {
                try {
                    let src;
                    if (req.body.id) {
                        FactoryDatabase_1.FactoryDatabase.loadSource(req.body.id).then((source) => {
                            Object.assign(source, req.body);
                            src = source;
                            return FactoryDatabase_1.FactoryDatabase.saveSource(src);
                        }).then((ret) => {
                            res.send(ret);
                        }).catch((err) => {
                            Logging_1.Logging.log('error', err);
                            res.status(501).send(err);
                        });
                    }
                    else {
                        // likely new source
                        src = new Source_1.Source(req.body);
                        FactoryDatabase_1.FactoryDatabase.saveSource(src).then((ret) => {
                            res.send(ret);
                        }).catch((err) => {
                            Logging_1.Logging.log('error', err);
                            res.status(501).send(err);
                        });
                    }
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.post('/api/updateModList', (req, res) => {
                try {
                    let modList = new ModList_1.ModList(req.body);
                    // req.body.mods might not be a list of strings...
                    FactoryDatabase_1.FactoryDatabase.saveModList(modList).then(() => {
                        res.send(modList);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/listTrials', (req, res) => {
                try {
                    let count = req.query.count ? req.query.count : 100;
                    FactoryDatabase_1.FactoryDatabase.listTrials(count).then((trials) => {
                        res.send(trials);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/listSources', (req, res) => {
                try {
                    let count = req.query.count ? Number.parseInt(req.query.count) : 100;
                    let showText = req.query.showText ? req.query.showText : false;
                    FactoryDatabase_1.FactoryDatabase.listSources(count).then((src) => {
                        if (showText != 'true')
                            src = src.map((s) => {
                                s.text = undefined;
                                return s;
                            });
                        res.send(src);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/listModLists', (req, res) => {
                try {
                    let count = req.query.count ? req.query.count : 100;
                    FactoryDatabase_1.FactoryDatabase.FactoryDB.getRepository(ModList_1.ModList).find({
                        take: count,
                    }).then((modLists) => {
                        res.send(modLists);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/loadTrial', (req, res) => {
                try {
                    let id = req.query.id;
                    FactoryDatabase_1.FactoryDatabase.loadTrial(id).then((trial) => {
                        res.send(trial);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/loadSource', (req, res) => {
                try {
                    let id = req.query.id;
                    FactoryDatabase_1.FactoryDatabase.loadSource(id).then((source) => {
                        res.send(source);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/loadModList', (req, res) => {
                try {
                    let id = req.query.id;
                    FactoryDatabase_1.FactoryDatabase.loadModList(id).then((modlist) => {
                        res.send(modlist);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/loadDatasetMetadata', (req, res) => {
                try {
                    let id = req.query.trialId;
                    if (!id)
                        throw new Error('Missing trialId');
                    FactoryDatabase_1.FactoryDatabase.loadDatasetMetadata(id).then((results) => {
                        res.send(results);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(500).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/loadDatasetRecords', (req, res) => {
                try {
                    let id = req.query.id;
                    let category = req.query.category;
                    if (category != 'item' && category != 'electric' && category != 'circuit' && category != 'pollution' && category != 'system') {
                        res.status(501).send('Invalid category');
                        return;
                    }
                    FactoryDatabase_1.FactoryDatabase.loadDatasetRecords(id, category).then((results) => {
                        res.send(results);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(500).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/modManager/listMods', (req, res) => {
                // load the filter options - if searching by name, needs to match even partially to the 'name', 'summary', 'title', 'category'
                let textFilter = req.query.textFilter ? req.query.textFilter : '';
                let category = req.query.category ? req.query.category : '';
                try {
                    let r = FactorioApi_1.FactorioApi.cachedModList.results.filter((o) => {
                        if (category != '' && o.category != category)
                            return false;
                        if (textFilter != '' && (!o.name.toLowerCase().includes(textFilter.toLowerCase()) ||
                            !o.summary.toLowerCase().includes(textFilter.toLowerCase()) ||
                            !o.title.toLowerCase().includes(textFilter.toLowerCase())))
                            return false;
                        return true;
                    });
                    res.send(r);
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(500).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/modManager/getModInfo', (req, res) => {
                try {
                    if (!req.query.name) {
                        res.status(501).send('Missing name');
                        return;
                    }
                    FactorioApi_1.FactorioApi.getModInfo(req.query.name).then((modInfo) => {
                        res.send(modInfo);
                    }).catch((e) => {
                        Logging_1.Logging.log('error', e);
                        res.status(501).send(e);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(500).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/cacheDataset/:id/:category', (req, res) => {
                try {
                    // when a dataset is used, if it isn't cached already it will be
                    // this function just does that process manually, if you know you're about to run a ton of queries at once
                    // this will query a dataset with params and return results
                    // the dataset being used (raw, with all data) will be cached for future usage
                    // this means that if you 'query' the same dataset multiple times (after this first), it will be fast and not need to re-load records from sql
                    let trialId = req.params.id;
                    let category = req.params.category;
                    FactoryDatabase_1.FactoryDatabase.loadDatasetRecords(trialId, category).then((results) => {
                        // cache dataset immediately
                        FactoryLocalBackend.cacheDataset(results, trialId, category);
                        res.send('OK');
                    }).catch((e) => {
                        Logging_1.Logging.log('error', e);
                        res.status(501).send(e);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(500).send(e);
                }
            });
            /*
            * #todo
            *   should make a system where the backend can cache a 'DatasetQuery' in memory so long as its used once every 15 minutes or so
            * if it needs to be re-run, it gets re-run and set in memory
            * this means immediate calls after a query will be fast, and not require re-parsing tons of data
            * */
            FactoryLocalBackend.app.post('/api/deleteTrialData', (req, res) => {
                try {
                    let id = req.body.id;
                    FactoryDatabase_1.FactoryDatabase.deleteTrialData(id).then((data) => {
                        res.send(data);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/clearTrialData/:id', (req, res) => {
                try {
                    FactoryDatabase_1.FactoryDatabase.deleteTrialData(req.params.id).then((data) => {
                        res.send('OK');
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/deleteTrial/:id', (req, res) => {
                try {
                    FactoryDatabase_1.FactoryDatabase.deleteTrial(req.params.id).then((data) => {
                        res.send('OK');
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/deleteSource/:id', (req, res) => {
                try {
                    FactoryDatabase_1.FactoryDatabase.deleteSource(req.params.id).then((data) => {
                        res.send('OK');
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(500).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/deleteModList/:id', (req, res) => {
                try {
                    FactoryDatabase_1.FactoryDatabase.deleteModList(req.params.id).then((data) => {
                        res.send('OK');
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(500).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/markTrialComplete/:id', (req, res) => {
                try {
                    FactoryDatabase_1.FactoryDatabase.loadTrial(req.params.id).then((trial) => {
                        if (!trial)
                            throw new Error('Invalid trial');
                        trial.stage = 'complete';
                        return FactoryDatabase_1.FactoryDatabase.saveTrial(trial);
                    }).then((data) => {
                        res.send('OK');
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/testAndSaveCredentials', (req, res) => {
                try {
                    const username = req.query.usr;
                    const token = req.query.token;
                    FactorioApi_1.FactorioApi.initialize({
                        username: username,
                        token: token,
                        dataPath: Factory_1.Factory.factoryDataPath
                    }).then(() => {
                        res.send('OK');
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.get('/api/dbInfo', (req, res) => {
                try {
                    if (FactoryDatabase_1.FactoryDatabase.FactoryDB)
                        res.send({
                            type: FactoryDatabase_1.FactoryDatabase.FactoryDB.options.type,
                            database: FactoryDatabase_1.FactoryDatabase.FactoryDB.options.database,
                        });
                    else
                        res.send('No database initialized');
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.app.post('/api/performTrialAction', (req, res) => __awaiter(this, void 0, void 0, function* () {
                try {
                    let execution = req.body.execution;
                    let trial = yield FactoryDatabase_1.FactoryDatabase.loadTrial(req.body.trial, true);
                    if (execution == 'prepare') {
                        Factory_1.Factory.prepareTrial(trial).then(() => {
                            return FactoryDatabase_1.FactoryDatabase.saveTrial(trial);
                        }).then((rtrial) => {
                            res.send(JSON.stringify({
                                trial: rtrial,
                                results: undefined
                            }));
                        }).catch((e) => {
                            Logging_1.Logging.log('error', e);
                            res.status(501).send(e);
                        });
                    }
                    else if (execution == 'compile') {
                        Factory_1.Factory.compileTrial(trial).then(() => {
                            return FactoryDatabase_1.FactoryDatabase.saveTrial(trial);
                        }).then((rtrial) => {
                            res.send(JSON.stringify({
                                trial: rtrial,
                                results: undefined
                            }));
                        }).catch((e) => {
                            Logging_1.Logging.log('error', e);
                            res.status(501).send(e);
                        });
                    }
                    else if (execution == 'run') {
                        Factory_1.Factory.runTrial(trial).then(() => {
                            // save to DB first!
                            return FactoryDatabase_1.FactoryDatabase.saveTrial(trial);
                        }).then((rtrial) => {
                            res.send(JSON.stringify({
                                trial: rtrial,
                                results: undefined
                            }));
                        }).catch((e) => {
                            Logging_1.Logging.log('error', e);
                            res.status(501).send(e);
                        });
                    }
                    else if (execution == 'analyze') {
                        // special case here - if this has already been run, we need to clear database data before re-running
                        if (!!trial.endedAt)
                            yield FactoryDatabase_1.FactoryDatabase.deleteTrialData(trial.id);
                        Factory_1.Factory.analyzeTrial(trial, true, true).then((results) => {
                            // save to DB first!
                            FactoryDatabase_1.FactoryDatabase.saveTrial(trial);
                            return { trial, results };
                        }).then(({ trial, results }) => {
                            trial.rawSystemText = undefined;
                            res.send(JSON.stringify({
                                trial: trial
                            }));
                        }).catch((e) => {
                            Logging_1.Logging.log('error', e);
                            res.status(501).send(e);
                        });
                    }
                    else {
                        res.status(501).send('Invalid execution type');
                        Logging_1.Logging.log('error', 'Invalid execution type');
                    }
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            }));
            FactoryLocalBackend.app.get('/api/datasetQuery/:id/:category/:func/:chunk', (req, res) => __awaiter(this, void 0, void 0, function* () {
                try {
                    // run a query based on passed in query params.
                    // we wont send a whole dataset in the request - so, we'll need to query for the data here first, then apply the query, then return the results
                    // query the Item table for the given dataset in queryid, then follow the filters as given in the r est of the query
                    let trialId = req.params.id;
                    let category = req.params.category;
                    let func = req.params.func;
                    let chunkSize = req.params.chunkSize;
                    let options = req.query.options;
                    let results = FactoryLocalBackend.cachedDatasets.get(trialId + '-' + category);
                    if (!results) {
                        results = yield FactoryDatabase_1.FactoryDatabase.loadDatasetRecords(trialId, category);
                        FactoryLocalBackend.cacheDataset(results, trialId, category);
                        if (!results)
                            throw new Error('No data found for dataset');
                    }
                    let q = new DatasetAnalysis_1.DatasetQuery(results.data, options);
                    if (func == 'uniqueLabels') {
                        let ret = q.uniqueLabels();
                        res.send(ret);
                        return;
                    }
                    else if (func == 'queryOptions') {
                        q.dataset = undefined;
                        res.send(q);
                        return;
                    }
                    else if (func == 'summaryByTickChunk' && chunkSize > 0) {
                        let ret = q.summaryByTickChunk(q.dataset, chunkSize);
                        res.send(ret);
                        return;
                    }
                    else if (func == 'summaryByLabel') {
                        let ret = q.summaryByLabel();
                        res.send(ret);
                        return;
                    }
                    else if (func == 'groupByTickChunk' && chunkSize > 0) {
                        let ret = q.groupByTickChunk(q.dataset, chunkSize);
                        res.send(ret);
                        return;
                    }
                    else if (func == 'groupByLabel') {
                        let ret = q.groupByLabel();
                        res.send(ret);
                        return;
                    }
                    else {
                        Logging_1.Logging.log('error', 'Invalid function');
                        res.status(501).send('Invalid function');
                    }
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            }));
            FactoryLocalBackend.app.get('/api/modManager/cacheModList/:id', (req, res) => {
                try {
                    let id = req.params.id;
                    FactoryDatabase_1.FactoryDatabase.loadModList(id).then((modlist) => {
                        return Factory_1.Factory.cacheModList(modlist);
                    }).then((dat) => {
                        res.send(dat);
                    }).catch((err) => {
                        Logging_1.Logging.log('error', err);
                        res.status(501).send(err);
                    });
                }
                catch (e) {
                    Logging_1.Logging.log('error', e);
                    res.status(501).send(e);
                }
            });
            FactoryLocalBackend.server = http.createServer(FactoryLocalBackend.app);
            /*FactoryLocalBackend.io = new Server<
                ClientToServerEvents,
                ServerToClientEvents,
                InterServerEvents,
                SocketData
            >(FactoryLocalBackend.server)*/
            return yield new Promise((resolve) => {
                console.log('starting server on 3001');
                FactoryLocalBackend.server.listen(port, () => {
                    resolve(null);
                });
            });
        });
    }
}
exports.FactoryLocalBackend = FactoryLocalBackend;
FactoryLocalBackend.cachedDatasets = new Map();
//# sourceMappingURL=FactoryLocalBackend.js.map