// @ts-check

////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////

const fs = require("fs");
const path = require("path");

const mysql = require("serverless-mysql");
const grabDbSSL = require("../../package-shared/utils/backend/grabDbSSL");

let connection = mysql({
    config: {
        host: process.env.DSQL_DB_HOST,
        user: process.env.DSQL_DB_USERNAME,
        password: process.env.DSQL_DB_PASSWORD,
        database: process.env.DSQL_DB_NAME,
        charset: "utf8mb4",
        ssl: grabDbSSL(),
    },
});

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

/**
 * # Main DB Handler Function
 * @async
 *
 * @param {object} params
 * @param {string} params.query
 * @param {string[] | object} [params.values]
 * @param {string} [params.database]
 *
 * @returns {Promise<any[] | object | null>}
 */
module.exports = async function dbHandler({ query, values, database }) {
    /**
     * Switch Database
     *
     * @description If a database is provided, switch to it
     */
    let isDbCorrect = true;

    if (database) {
        connection = mysql({
            config: {
                host: process.env.DSQL_DB_HOST,
                user: process.env.DSQL_DB_USERNAME,
                password: process.env.DSQL_DB_PASSWORD,
                database: database,
                charset: "utf8mb4",
                ssl: grabDbSSL(),
            },
        });
    }

    if (!isDbCorrect) {
        console.log(
            "Shell Db Handler ERROR in switching Database! Operation Failed!"
        );
        return null;
    }

    /**
     * Declare variables
     *
     * @description Declare "results" variable
     */
    let results;

    /**
     * Fetch from db
     *
     * @description Fetch data from db if no cache
     */
    try {
        if (query && values) {
            results = await connection.query(query, values);
        } else {
            results = await connection.query(query);
        }

        /** ********************* Clean up */
        await connection.end();
    } catch (/** @type {any} */ error) {
        if (process.env.FIRST_RUN) {
            return null;
        }

        console.log("ERROR in dbHandler =>", error.message);
        console.log(error);
        console.log(connection.config());

        fs.appendFileSync(
            path.resolve(__dirname, "../.tmp/dbErrorLogs.txt"),
            JSON.stringify(error, null, 4) + "\n" + Date() + "\n\n\n",
            "utf8"
        );
        results = null;
    }

    /**
     * Return results
     *
     * @description Return results add to cache if "req" param is passed
     */
    if (results) {
        return JSON.parse(JSON.stringify(results));
    } else {
        return null;
    }
};
