"use strict";

const pg = require('pg');
const config = require('./config.js');

class Database {
    constructor(databaseName)
    {
        this._client = null;
        this._databaseName = databaseName || config.value('database.name');
    }

    _prepareSSLConfig()
    {
        if (!config.value('database.ssl') || config.value('database.ssl.mode') == 'disable')
            return '';

        const certificateConfigs = ['?ssl=true'];
        for(const key of ['cert', 'key', 'rootcert']) {
            const fullKey = `database.ssl.${key}`;
            let path = config.value(fullKey);
            if (!path)
                continue
            if (path[0] != '/')
                path = config.path(fullKey);
            certificateConfigs.push(`${key}=${path}`);
        }
        return certificateConfigs.join('&');
    }

    connect(options)
    {
        console.assert(this._client === null);

        let username = config.value('database.username');
        let password = config.value('database.password');
        let host = config.value('database.host');
        let port = config.value('database.port');

        // No need to worry about escaping strings since they are only set by someone who can write to config.json.
        let connectionString = `tcp://${username}:${password}@${host}:${port}/${this._databaseName}${this._prepareSSLConfig()}`;

        let client = new pg.Client(connectionString);
        if (!options || !options.keepAlive)
            client.on('drain', this.disconnect.bind(this));

        this._client = client;

        return new Promise(function (resolve, reject) {
            client.connect(function (error) {
                if (error)
                    reject(error);
                resolve();
            });
        });
    }

    disconnect()
    {
        if (this._client) {
            this._client.end();
            this._client = null;
        }
    }

    query(statement, parameters)
    {
        console.assert(this._client);
        var client = this._client;
        return new Promise(function (resolve, reject) {
            client.query(statement, parameters || [], function (error, result) {
                if (error)
                    reject(error);
                else
                    resolve(result);
            });
        });
    }

    selectAll(table, columnToSortBy)
    {
        return this.selectRows(table, {}, {sortBy: columnToSortBy});
    }

    selectFirstRow(table, params, columnToSortBy)
    {
        return this.selectRows(table, params, {sortBy: columnToSortBy, limit: 1}).then(function (rows) {
            return rows[0];
        });
    }

    selectRows(table, params, options)
    {
        let prefix = '';
        if (table in tableToPrefixMap)
            prefix = tableToPrefixMap[table] + '_';

        options = options || {};

        let columnNames = [];
        let placeholders = [];
        let values = [];
        for (let name in params) {
            columnNames.push(prefix + name);
            placeholders.push('$' + columnNames.length);
            values.push(params[name]);
        }

        let qualifier = '';
        if (columnNames.length)
            qualifier += ` WHERE (${columnNames.join(',')}) = (${placeholders.join(',')})`;
        qualifier += ` ORDER BY ${prefix}${options.sortBy || 'id'}`;
        if (options && options.limit)
            qualifier += ` LIMIT ${options.limit}`;

        return this.query(`SELECT * FROM ${table}${qualifier}`, values).then(function (result) {
            return result.rows.map(function (row) {
                let formattedResult = {};
                for (let columnName in row) {
                    let formattedName = columnName;
                    if (formattedName.startsWith(prefix))
                        formattedName = formattedName.substring(prefix.length);
                    formattedResult[formattedName] = row[columnName];
                }
                return formattedResult;
            });
        });
    }

    insert(table, parameters)
    {
        let columnNames = [];
        let placeholders = [];
        let values = [];
        for (let name in parameters) {
            values.push(parameters[name]);
            if (table in tableToPrefixMap)
                name = tableToPrefixMap[table] + '_' + name;
            columnNames.push(name);
            placeholders.push(`\$${placeholders.length + 1}`);
        }
        return this.query(`INSERT INTO ${table} (${columnNames}) VALUES (${placeholders})`, values);
    }
}

const tableToPrefixMap = {
    'aggregators': 'aggregator',
    'analysis_strategies': 'strategy',
    'analysis_tasks': 'task',
    'analysis_test_groups': 'testgroup',
    'bug_trackers': 'tracker',
    'build_triggerables': 'triggerable',
    'build_requests': 'request',
    'build_workers': 'worker',
    'builds': 'build',
    'builders': 'builder',
    'commits': 'commit',
    'commit_ownerships': 'commit',
    'committers': 'committer',
    'test_configurations': 'config',
    'test_metrics': 'metric',
    'test_runs': 'run',
    'tests': 'test',
    'tracker_repositories': 'tracrepo',
    'triggerable_configurations': 'trigconfig',
    'triggerable_repository_groups': 'repositorygroup',
    'triggerable_repositories': 'trigrepo',
    'triggerable_configuration_repetition_types': 'configrepetition',
    'platforms': 'platform',
    'platform_groups': 'platformgroup',
    'reports': 'report',
    'repositories': 'repository',
    'commit_sets': 'commitset',
    'commit_set_items': 'commitset',
    'run_iterations': 'iteration',
    'uploaded_files': 'file',
}

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