const { remote, ipcRenderer, shell } = require('electron');
const path = require('path');
const fs = require('fs');

const package = require(`${remote.app.getAppPath()}/package.json`);
const protocolStr = 'flast';
const fileProtocolStr = `${protocolStr}-file`;

const Config = require('electron-store');
const config = new Config();

// ファイルタイプの列挙体（のつもり）
const FileType = {
    File: 'file',
    Directory: 'directory',
    Unknown: 'unknown'
}

/**
 * ファイルの種類を取得する
 * @param {string} path パス
 * @return {FileType} ファイルの種類
 */
const getFileType = path => {
    try {
        const stat = fs.statSync(path);

        switch (true) {
            case stat.isFile():
                return FileType.File;

            case stat.isDirectory():
                return FileType.Directory;

            default:
                return FileType.Unknown;
        }

    } catch (e) {
        return FileType.Unknown;
    }
}

/**
 * 指定したディレクトリ配下のすべてのファイルをリストアップする
 * @param {string} dirPath 検索するディレクトリのパス
 * @return {Array<string>} ファイルのパスのリスト
 */
const listFiles = dirPath => {
    const ret = [];
    const paths = fs.readdirSync(dirPath);

    paths.forEach(a => {
        const path = `${dirPath}/${a}`;

        switch (getFileType(path)) {
            case FileType.File:
                ret.push(path);
                break;

            case FileType.Directory:
                ret.push(...listFiles(path));
                break;

            default:
            /* noop */
        }
    })

    return ret;
};

/*
// ====================================================================== //
// ====================================================================== //
// ====================================================================== //
*/

global.getConfigPath = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.path;
}

global.getFiles = (pathName) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return listFiles(path.resolve(__dirname, pathName));
}

global.getFile = (path, json = false) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    if (json) {
        return require(path);
    } else {
        const text = fs.readFileSync(path, 'utf8');
        return text;
    }
}

/*
// ====================================================================== //
// ====================================================================== //
// ====================================================================== //
*/

global.openInEditor = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.openInEditor();
}

/*
// ====================================================================== //
// ====================================================================== //
// ====================================================================== //
*/

global.getAppName = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return package.name;
}

global.getAppDescription = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return package.description;
}

global.getAppVersion = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return package.version;
}

global.getAppChannel = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return package.flast_channel;
}


global.getChromiumVersion = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return process.versions['chrome'];
}

/*
// ====================================================================== //
// ====================================================================== //
// ====================================================================== //
*/

global.clearBrowserData = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    b && ipcRenderer.send('clear-browsing-data', {});
}

/*
// ====================================================================== //
// ====================================================================== //
// ====================================================================== //
*/

global.updateFilters = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    ipcRenderer.send('update-filters', {});
}

/*
// ====================================================================== //
// ====================================================================== //
// ====================================================================== //
*/

global.getHistorys = () => new Promise((resolve) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    ipcRenderer.send('data-history-get', {});
    ipcRenderer.on('data-history-get', (e, args) => {
        resolve(args.historys);
    });
});

global.clearHistorys = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    b && ipcRenderer.send('data-history-clear', {});
}

global.getDownloads = () => new Promise((resolve) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    ipcRenderer.send('data-downloads-get', {});
    ipcRenderer.on('data-downloads-get', (e, args) => {
        resolve(args.downloads);
    });
});

global.clearDownloads = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    b && ipcRenderer.send('data-downloads-clear', {});
}

global.getBookmarks = (isPrivate) => new Promise((resolve) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    ipcRenderer.send('data-bookmarks-get', { isPrivate });
    ipcRenderer.on('data-bookmarks-get', (e, args) => {
        resolve(args.bookmarks);
    });
});

global.clearBookmarks = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    b && ipcRenderer.send('data-bookmarks-clear', {});
}

/*
// ====================================================================== //
// ====================================================================== //
// ====================================================================== //
*/

global.getApps = () => new Promise((resolve) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    ipcRenderer.send('data-apps-get', {});
    ipcRenderer.on('data-apps-get', (e, args) => {
        resolve(args.apps);
    });
});

global.clearApps = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    b && ipcRenderer.send('data-apps-clear', {});
}

/*
// ====================================================================== //
// ====================================================================== //
// ====================================================================== //
*/

global.getHomeButton = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('design.isHomeButton');
}

global.setHomeButton = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('design.isHomeButton', b);
    ipcRenderer.send('window-change-settings', {});
}

global.getBookmarkBar = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('design.isBookmarkBar');
}

global.setBookmarkBar = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('design.isBookmarkBar', b);
    ipcRenderer.send('window-change-settings', {});
    ipcRenderer.send('window-fixBounds', {});
}

global.getDarkTheme = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('design.isDarkTheme');
}

global.setDarkTheme = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('design.isDarkTheme', b);
    ipcRenderer.send('window-change-settings', {});
}

global.getCustomTitlebar = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('design.isCustomTitlebar');
}

global.setCustomTitlebar = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('design.isCustomTitlebar', b);
}

global.getDefaultHomePage = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('homePage.isDefaultHomePage');
}

global.setDefaultHomePage = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('homePage.isDefaultHomePage', b);
}

global.getStartPage = (b = true) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return b ? (config.get('homePage.isDefaultHomePage') ? `${protocolStr}://home/` : config.get('homePage.defaultPage')) : config.get('homePage.defaultPage');
}

global.setStartPage = (url) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('homePage.defaultPage', url);
}

global.getSearchEngines = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('searchEngine.searchEngines');
}

global.getSearchEngine = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    for (var i = 0; i < config.get('searchEngine.searchEngines').length; i++) {
        if (config.get('searchEngine.searchEngines')[i].name == config.get('searchEngine.defaultEngine')) {
            return config.get('searchEngine.searchEngines')[i];
        }
    }
}

global.setSearchEngine = (name) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    getSearchEngines().some((item, i) => {
        if (item.name && item.name === name)
            config.set('searchEngine.defaultEngine', name);
    });
}

global.getMedia = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('pageSettings.media');
}

global.setMedia = (v) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('pageSettings.media', v);
}

global.getGeolocation = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('pageSettings.geolocation');
}

global.setGeolocation = (v) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('pageSettings.geolocation', v);
}

global.getNotifications = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('pageSettings.notifications');
}

global.setNotifications = (v) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('pageSettings.notifications', v);
}

global.getMidiSysex = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('pageSettings.midiSysex');
}

global.setMidiSysex = (v) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('pageSettings.midiSysex', v);
}

global.getPointerLock = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('pageSettings.pointerLock');
}

global.setPointerLock = (v) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('pageSettings.pointerLock', v);
}

global.getFullScreen = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('pageSettings.fullscreen');
}

global.setFullScreen = (v) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('pageSettings.fullscreen', v);
}

global.getOpenExternal = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('pageSettings.openExternal');
}

global.setOpenExternal = (v) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('pageSettings.openExternal', v);
}

global.getAdBlock = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    return config.get('isAdBlock');
}

global.setAdBlock = (b) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    config.set('isAdBlock', b);
    ipcRenderer.send('window-change-settings', {});
}

global.restart = () => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;

    remote.app.relaunch();
    remote.app.exit(0);
}

global.isURL = (input) => {
    const pattern = /^((?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)|flast:\/\/\S.*|flast-file:\/\/\S.*|file:\/\/\S.*)\S*$/;

    if (pattern.test(input)) {
        return true;
    }
    return pattern.test(`http://${input}`);
};

global.installApp = (id, name, description, url) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://` || location.hostname !== 'store.aoichaan0513.xyz' || location.host !== 'localhost:3000')) return;

    ipcRenderer.send('data-apps-add', { id, name, description, url });
}

global.isInstallApp = (id) => new Promise((resolve) => {
    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://` || location.hostname !== 'store.aoichaan0513.xyz' || location.host !== 'localhost:3000')) return;

    ipcRenderer.send('data-apps-is', { id });
    ipcRenderer.once('data-apps-is', (e, args) => {
        console.log(args.id, args.isInstalled)
        resolve([args.id, args.isInstalled]);
    });
});

onload = function () {
    // console.log(document.documentElement.innerText);

    if (location.protocol === `${protocolStr}:` || location.protocol === `${fileProtocolStr}://` || location.hostname === 'store.aoichaan0513.xyz' || location.host === 'localhost:3000') return;

    delete global.getConfigPath;
    delete global.getFiles;
    delete global.getFile;
    delete global.clearBrowserData;
    delete global.updateFilters;
    delete global.getHistorys;
    delete global.clearHistory;
    delete global.getBookmarks;
    delete global.clearBookmark;
    delete global.getHomeButton;
    delete global.setHomeButton;
    delete global.getDarkTheme;
    delete global.setDarkTheme;
    delete global.getStartPage;
    delete global.setStartPage;
    delete global.getSearchEngines;
    delete global.getSearchEngine;
    delete global.setSearchEngine;
    delete global.getAdBlocker;
    delete global.setAdBlocker;
    delete global.getCustomTitlebar;
    delete global.setCustomTitlebar;
    delete global.restart;
    delete global.isURL;

    delete global.installApp;
    delete global.isInstallApp;
}

onmousedown = (e) => {
    if (remote.getCurrentWindow().getBrowserView() == undefined) return;
    const view = remote.getCurrentWindow().getBrowserView();

    if (e.button == 3) {
        if (view.webContents.canGoBack())
            view.webContents.goBack();
    } else if (e.button == 4) {
        if (view.webContents.canGoForward())
            view.webContents.goForward();
    }
}