const { app } = require('electron');
const log = require('electron-log');
const fs = require('fs');
const path = require('path');
const fetch = require('node-fetch');
const http = require('http');
const mime = require('mime-types');

const buttonsModule = require("../modules/buttons/buttons");
const getAppWindow = require('../modules/getAppWindow.js');
const heshChecker = require('../modules/hesh-checker');
const getParams = require('../modules/get-params');
const promiseTimeout = require('../modules/timeout-for-promise.js');

let server;
let lastDataFileNames = {
    _ads: false,
    _info: false,
    _button: false
};
let isBlockPlayButtons = false;
let isInited = false;

const createServer = (serverPort) => {
    try {
        if (isInited) {
            return;
        }

        isInited = true;

        const port = serverPort;
        const neuroAdWindow = getAppWindow('main');

        const requestHandler = (request, response) => {
            if (request.url === '/') {
                // TODO: response for old app versions 1.1.61 and older
                response.end(JSON.stringify({ "permitDownload": "false" }));
            } else if (request.url === '/check-content/' && request.method === 'POST' && request.headers['content-type'] === 'application/json') {
                let body = '';

                request.on('data', chunk => body += chunk.toString());
                request.on('end', () => {
                    const data = JSON.parse(body);
                    let answer = 'ok';

                    for (let i = 0; i < data.length; i++) {
                        if (!heshChecker.find(data[i].path, data[i].hesh) || !heshChecker.check(data[i].path, data[i].hesh)) {
                            answer = 'check failed';

                            response.end(answer);

                            break;
                        }
                    }

                    response.end(answer);
                });
            } else {
                //обрабатываем запросы по кнопкам
                let params = {  //параметры для обработки
                    content_path: path.resolve(app.getPath('userData'), 'buttonsData'),
                    //content_path: "./buttons_module/data",
                    onclick: function (event) {  //событие нажатия кнопки
                        event.content_path = params.content_path;
                        //читаем index.js для требуемого события кнопки
                        let script_path = path.resolve(event.content_path, 'button_events/event_' + event.event_id + "/index.js");
                        event.script = "";
                        if (fs.existsSync(script_path)) {
                            event.script = fs.readFileSync(script_path);
                        }
                        log.info(event.event_id);

                        neuroAdWindow.webContents.send('Button', event);
                    },
                    isBlockPlayButtons: isBlockPlayButtons,
                    lastUpdate: (lastDataFileNames._button ? lastDataFileNames._button.substr(0, lastDataFileNames._button.indexOf('_')) : false)
                };

                //проверяем, относится ли запрос к кнопкам. если да, то он обрабатывается этой функцией и возвращает true
                //иначе возвращает false
                if (buttonsModule.processRequest(request, response, params)) return;

                let filePath = path.join(app.getPath('userData'), decodeURI(request.url));

                if (fs.existsSync(filePath)) {
                    let stat = fs.statSync(filePath);

                    response.writeHead(200, {
                        'Content-Type': mime.lookup(filePath),
                        'Content-Length': stat.size
                    });

                    log.info(`upload file: ${filePath} for machine: ${request.connection.remoteAddress}`);

                    let readStream = fs.createReadStream(filePath);
                    // We replaced all the event handlers with a simple call to readStream.pipe()
                    try { readStream.pipe(response); } catch (e) {
                        console.error(e);
                    }
                } else {
                    log.warn('no such file for uploading ' + filePath);
                    response.end(JSON.stringify({ error: 'no such file for uploading ' + filePath }));
                }
            }
        };

        if (!server) {
            const serverUrl = 'http://localhost:' + port;

            log.debug('[ServerWorker] check serverUrl', serverUrl)

            promiseTimeout(fetch(serverUrl, {
                cache: 'no-cache'
            }))
                .then(() => {
                    log.warn('port: ' + port + ' already used.', 'server don\'t created');
                })
                .catch(() => {
                    server = http.createServer(requestHandler);

                    server.listen(port, (err) => {
                        if (err) {
                            return log.error('something bad happened', err);
                        }
                        log.info(`server is listening on ${port}`);
                    });

                    buttonsModule.startADB();
                    buttonsModule.startButtonsAPK();
                });
        } else {
            log.info('Server is already exists!');
        }
    } catch (err) {
        log.error('index:createServer()', err);
    }
};

module.exports = createServer;
