const mysql = require('mysql2/promise');
const config = require('./config.js');
const fs = require('fs-extra');

module.exports = {
    init() {
        if (!this.pool) {
            this.pool = mysql.createPool(config.mysql);
            this.pool.on('connection', connection => {
                connection.config.namedPlaceholders = true;
            });
        }
    },

    /**
     * Makes a query from a raw sql
     * @param {String} query - The raw SQL query
     * @param {Object} params - Parameterized values
     *
     * @return {Object} - Result promise
     */
    rawSql(query, params) {
        return this.pool.query(query, params).then(([rows]) => {
            return rows;
        });
    },

    /**
     * Makes a query from a SQL file
     * @param {String} queryName - The SQL file name
     * @param {Object} params - Parameterized values
     *
     * @return {Object} - Result promise
     */
    rawSqlFromDef(queryName, params) {
        const query = fs.readFileSync(`${queryName}.sql`, 'utf8');

        return this.rawSql(query, params);
    },

    /**
     * Returns the first row from a given raw sql
     * @param {String} query - The raw SQL query
     * @param {Object} params - Parameterized values
     *
     * @return {Object} - Result promise
     */
    findOne(query, params) {
        return this.rawSql(query, params).then(([row]) => row);
    },

    /**
     * Returns the first row from a given SQL file
     * @param {String} queryName - The SQL file name
     * @param {Object} params - Parameterized values
     *
     * @return {Object} - Result promise
     */
    findOneFromDef(queryName, params) {
        return this.rawSqlFromDef(queryName, params)
            .then(([row]) => row);
    },

    /**
     * Returns the first property from a given raw sql
     * @param {String} query - The raw SQL query
     * @param {Object} params - Parameterized values
     *
     * @return {Object} - Result promise
     */
    findValue(query, params) {
        return this.findOne(query, params).then(row => {
            return Object.values(row)[0];
        });
    },

    /**
     * Returns the first property from a given SQL file
     * @param {String} queryName - The SQL file name
     * @param {Object} params - Parameterized values
     *
     * @return {Object} - Result promise
     */
    findValueFromDef(queryName, params) {
        return this.findOneFromDef(queryName, params).then(row => {
            return Object.values(row)[0];
        });
    }
};