'use strict';

const assert = require('assert');
const childProcess = require('child_process');
const fs = require('fs');
const path = require('path');

const Config = require('../../tools/js/config.js');
const Database = require('../../tools/js/database.js');
const RemoteAPI = require('../../tools/js/remote.js').RemoteAPI;
const BrowserPrivilegedAPI = require('../../public/v3/privileged-api.js').PrivilegedAPI;
const NodePrivilegedAPI = require('../../tools/js/privileged-api').PrivilegedAPI;

class TestServer {
    constructor()
    {
        this._pidFile = null;
        this._testConfigPath = Config.path('testServer.config');
        this._dataDirectory = Config.path('dataDirectory');
        this._backupDataPath = null;
        this._pidWaitStart = null;
        this._shouldLog = false;
        this._pgsqlDirectory = null;
        this._server = null;

        this._databaseName = Config.value('testDatabaseName');
        this._databaseUser = Config.value('database.username');
        this._databaseHost = Config.value('database.host');
        this._databasePort = Config.value('database.port');
        this._database = null;

        this._remote = null
    }

    start()
    {
        let testConfigContent = this.testConfig();
        fs.writeFileSync(this._testConfigPath, JSON.stringify(testConfigContent, null, '    '));

        this._ensureTestDatabase();
        this._ensureDataDirectory();

        return this._startApache();
    }

    stop()
    {
        this._restoreDataDirectory();

        return this._stopApache();
    }

    remoteAPI()
    {
        assert(this._remote);
        return this._remote;
    }

    database()
    {
        assert(this._databaseName);
        if (!this._database)
            this._database = new Database(this._databaseName);
        return this._database;
    }

    testConfig()
    {
        return {
            'siteTitle': 'Test Dashboard',
            'debug': true,
            'jsonCacheMaxAge': 600,
            'dataDirectory': Config.value('dataDirectory'),
            'database': {
                'host': Config.value('database.host'),
                'port': Config.value('database.port'),
                'username': Config.value('database.username'),
                'password': Config.value('database.password'),
                'name': Config.value('testDatabaseName'),
            },
            'uploadFileLimitInMB': 2,
            'uploadUserQuotaInMB': 5,
            'uploadTotalQuotaInMB': 7,
            'uploadDirectory': Config.value('dataDirectory') + '/uploaded',
            'universalSlavePassword': null,
            'maintenanceMode': false,
            'clusterStart': [2000, 1, 1, 0, 0],
            'clusterSize': [0, 2, 0],
            'defaultDashboard': [[]],
            'dashboards': {},
            'summaryPages': []
        }
    }

    _ensureDataDirectory()
    {
        let backupPath = path.resolve(this._dataDirectory, '../original-data');
        if (fs.existsSync(this._dataDirectory)) {
            assert.ok(!fs.existsSync(backupPath), `Both ${this._dataDirectory} and ${backupPath} exist. Cannot make a backup of data`);
            fs.renameSync(this._dataDirectory, backupPath);
            this._backupDataPath = backupPath;
        } else if (fs.existsSync(backupPath)) // Assume this is a backup from the last failed run
            this._backupDataPath = backupPath;
        fs.mkdirSync(this._dataDirectory, 0o755);
        fs.mkdirSync(path.resolve(this._dataDirectory, 'uploaded'), 0o755);
    }

    _restoreDataDirectory()
    {
        childProcess.execFileSync('rm', ['-rf', this._dataDirectory]);
        if (this._backupDataPath)
            fs.renameSync(this._backupDataPath, this._dataDirectory);
    }

    cleanDataDirectory()
    {
        let fileList = fs.readdirSync(this._dataDirectory);
        for (let filename of fileList) {
            if (filename != 'uploaded')
                fs.unlinkSync(path.resolve(this._dataDirectory, filename));
        }
        fileList = fs.readdirSync(path.resolve(this._dataDirectory, 'uploaded'));
        for (let filename of fileList)
            fs.unlinkSync(path.resolve(this._dataDirectory, 'uploaded', filename));
    }

    _ensureTestDatabase()
    {
        try {
            this._executePgsqlCommand('dropdb');
        } catch (error) { }
        this._executePgsqlCommand('createdb');
        this._executePgsqlCommand('psql', ['--command', `grant all privileges on database "${this._databaseName}" to "${this._databaseUser}";`]);
        this.initDatabase();
    }

    initDatabase()
    {
        if (this._database)
            this._database.disconnect();
        this._database = null;

        const initFilePath = Config.pathFromRoot('init-database.sql');
        const migrateFilePath = Config.pathFromRoot('migrate-database.sql');
        for (const filePath of [initFilePath, migrateFilePath]) {
            this._executePgsqlCommand('psql', ['--username', this._databaseUser, '--file', filePath],
                {stdio: ['ignore', 'ignore', 'ignore']});
        }
    }

    _executePgsqlCommand(command, args, options)
    {
        if (!this._pgsqlDirectory)
            this._pgsqlDirectory = this._determinePgsqlDirectory();
        childProcess.execFileSync(path.resolve(this._pgsqlDirectory, command),
            [this._databaseName, '--host', this._databaseHost, '--port', this._databasePort].concat(args || []), options);
    }

    _determinePgsqlDirectory()
    {
        try {
            let initdbLocation = childProcess.execFileSync('which', ['initdb']).toString();
            return path.dirname(initdbLocation);
        } catch (error) {
            let serverPgsqlLocation = '/Applications/Server.app/Contents/ServerRoot/usr/bin/';
            childProcess.execFileSync(path.resolve(serverPgsqlLocation, 'initdb'), ['--version']);
            return serverPgsqlLocation;
        }
    }

    _startApache()
    {
        let pidFile = Config.path('testServer.httpdPID');
        let httpdConfig = Config.path('testServer.httpdConfig');
        let port = Config.value('testServer.port');
        let errorLog = Config.path('testServer.httpdErrorLog');
        let mutexFile = Config.path('testServer.httpdMutexDir');
        let phpVersion = childProcess.execFileSync('php', ['-v'], {stdio: ['pipe', 'pipe', 'ignore']}).toString().includes('PHP 5') ? 'PHP5' : 'PHP7';

        if (!fs.existsSync(mutexFile))
            fs.mkdirSync(mutexFile, 0o755);

        let args = [
            '-f', httpdConfig,
            '-c', `SetEnv ORG_WEBKIT_PERF_CONFIG_PATH ${this._testConfigPath}`,
            '-c', `Listen ${port}`,
            '-c', `PidFile ${pidFile}`,
            '-c', `ErrorLog ${errorLog}`,
            '-c', `Mutex file:${mutexFile}`,
            '-c', `DocumentRoot ${Config.serverRoot()}`,
            '-D', phpVersion];

        if (this._shouldLog)
            console.log(args);

        childProcess.execFileSync('httpd', args);

        this._server = {
            scheme: 'http',
            host: 'localhost',
            port: port,
        };
        this._pidWaitStart = Date.now();
        this._pidFile = pidFile;

        this._remote = new RemoteAPI(this._server);

        return new Promise(this._waitForPid.bind(this, true));
    }

    _stopApache()
    {
        if (!this._pidFile)
            return;

        let pid = fs.readFileSync(this._pidFile, 'utf-8').trim();

        if (this._shouldLog)
            console.log('Stopping', pid);

        childProcess.execFileSync('kill', ['-TERM', pid]);

        this._pidWaitStart = Date.now();
        return new Promise(this._waitForPid.bind(this, false));
    }

    _waitForPid(shouldExist, resolve, reject)
    {
        if (fs.existsSync(this._pidFile) != shouldExist) {
            if (Date.now() - this._pidWaitStart > 8000)
                reject();
            else
                setTimeout(this._waitForPid.bind(this, shouldExist, resolve, reject), 100);
            return;
        }
        resolve();
    }

    inject(privilegedAPIType='browser')
    {
        console.assert(privilegedAPIType === 'browser' || privilegedAPIType === 'node');
        const useNodePrivilegedAPI = privilegedAPIType === 'node';
        const self = this;
        before(function () {
            this.timeout(10000);
            return self.start();
        });

        let originalRemote;
        let originalPrivilegedAPI;

        beforeEach(function () {
            this.timeout(10000);
            self.initDatabase();
            self.cleanDataDirectory();
            originalRemote = global.RemoteAPI;
            global.RemoteAPI = self._remote;
            self._remote.clearCookies();

            originalPrivilegedAPI = global.PrivilegedAPI;
            global.PrivilegedAPI = useNodePrivilegedAPI ? NodePrivilegedAPI : BrowserPrivilegedAPI;

            if (!useNodePrivilegedAPI) {
                global.PrivilegedAPI._token = null;
                global.PrivilegedAPI._expiration = null;
            }
        });

        after(function () {
            this.timeout(10000);
            global.RemoteAPI = originalRemote;
            global.PrivilegedAPI = originalPrivilegedAPI;
            return self.stop();
        });
    }
}

if (!global.TestServer)
    global.TestServer = new TestServer;

if (typeof module != 'undefined')
    module.exports = global.TestServer;
