const {app} = require('electron');
const {download} = require('electron-dl');
const path = require("path");
const url = require("url");
const log = require('electron-log');// error // warn // info // verbose // debug // silly

const getAppWindow = require('../getAppWindow.js');
const reboot = require('../reboot');
const heshChecker = require('../hesh-checker');
const checkItemsOnLocalMachine = require('./check-items-on-local-machine');
const getItemsForDownload = require('./get-items-for-download');
const downloadItemDone = require('./then-download-done');

let isStop = false;
let isDisabled = false;
let isFirstInit = true;
let isDownloading = false;

const setEvents = (neuroAdWindow) => {
    try {
        neuroAdWindow.webContents.session.on('will-download', downloadEvents);
    } catch (err) {
        log.error('mod:content-loader setEvents() broken', err);
    }
};
const downloadItem = (item, downloadUrl) => {
    try {
        return new Promise((resolve, reject) => {
            const neuroAdWindow = getAppWindow('main');

            download(neuroAdWindow, url.resolve(downloadUrl, item.path), {
                directory: path.parse(path.join(app.getPath('userData'), item.path)).dir
            })
                .then((re) => {
                    if ( downloadItemDone(item.path, item.hesh) ) {
                        log.info(`Download item: ${item.path} done`);

                        resolve();
                    } else {
                        log.error(`Download item: ${item.path} has broken`);

                        reject();
                    }
                })
                .catch((err) => {
                    log.error(err);
                });
        });
    } catch (err) {
        log.error('mod:content-loader downloadItem() broken', err);
    }

};
const downloader = function (newData, mainMachineUrl, remoteServerUrl) {
    try {
        return new Promise(function (resolve, reject) {
            if ( isDisabled ) {
                log.warn('content downloader is disabled');
                reject();
            }

            const neuroAdWindow = getAppWindow('main');
            let downloadUrl = null;

            if ( isFirstInit ) {
                setEvents(neuroAdWindow);

                isFirstInit = false;
            } else if ( isDownloading ) {
                isStop = true;
                log.error('don\'t start new downloading, init stop current downloading');
                reject();
            }

            isDownloading = true;

            const toDownloadArr = getItemsForDownload(newData);
            const goNextItem = () => {
                if ( isStop ) {
                    log.info('downloading is stopped');
                    isStop = false;
                    isDownloading = false;
                    reject();
                } else if ( toDownloadArr.length > 0 ) {
                    downloadItem(toDownloadArr[0], downloadUrl)
                        .then(() => {
                            toDownloadArr.shift();

                            goNextItem();
                        })
                        .catch((err) => {
                            log.error(err);
                            isStop = false;
                            isDownloading = false;
                            reject();
                        });
                } else {
                    isStop = false;
                    isDownloading = false;
                    resolve();
                }
            };

            if ( !mainMachineUrl ) {
                downloadUrl = remoteServerUrl;
                goNextItem();
            } else if ( toDownloadArr.length > 0 ) {
                checkItemsOnLocalMachine.checkAll(toDownloadArr, mainMachineUrl)
                    .then((re) => {
                        if ( re === 'ok' ) {
                            downloadUrl = mainMachineUrl;
                            goNextItem();
                        } else {
                            isDownloading = false;
                            reject();
                        }
                    })
                    .catch(() => {
                        downloadUrl = remoteServerUrl;
                        goNextItem();
                    });
            } else {
                log.info('mod:content-loader', 'nothing to download');
                isStop = false;
                isDownloading = false;
                resolve();
            }
        });
    } catch (err) {
        log.error('mod:content-loader', err);
    }
};


const downloadEvents = function (event, item, webContents) {
    item.on('updated', function (event, state) {
        try {
            if ( isStop ) {
                return item.cancel();
            }

            switch ( state ) {
                case 'interrupted':
                    log.info(`Downloading interrupted but can be resumed`);
                    break;
                case 'progressing':
                    if ( item.isPaused() ) {
                        log.info(`Download item is paused`);
                    } else {
                        const mb = (item.getReceivedBytes() / 1048576).toFixed(4);
                        log.info(`Ricive: ${mb}Mb`);
                    }
                    break;
            }
        } catch (err) {
            log.error('downloading update event', err);
        }
    });

    item.on('done', function (event, state) {
        try {

            switch ( state ) {
                case 'completed':
                    log.info('completed');
                    break;
                case 'cancelled':
                    log.info('cancelled');
                    break;
                case 'interrupted':
                    log.info('interrupted');
                    break;
            }
        } catch (err) {
            log.error('downloading done event');
        }
    });
};
const stop = function () {
    try {
        log.info('mod:content-loader is stopped');

        isStop = true;
    } catch (err) {
        log.error('mod:content-loader', err);
    }
};
const disable = function () {
    try {
        log.info('mod:content-loader is disabled');

        isStop = true;
        isDisabled = true;
    } catch (err) {
        log.error('mod:content-loader', err);
    }
};
const enable = function () {
    try {
        log.info('mod:content-loader is enabled');

        isStop = false;
        isDisabled = false;
    } catch (err) {
        log.error('mod:content-loader', err);
    }
};
const removeHeshes = function () {
    try {
        heshChecker.clearFile();

        if ( process.platform === 'linux' ) {
            reboot.roskomnadzor();
        }
    } catch (err) {
        log.error('mod:content-loader', err);
    }
};
const checkIsDownloading = () => {
    try {
        return isDownloading;
    } catch (err) {
        log.error('mod:content-loader', err);
    }
};

module.exports = {
    download: downloader,
    stop: stop,
    disable: disable,
    enable: enable,
    removeHeshes: removeHeshes,
    isDownloading: checkIsDownloading
};
