import { IConfig } from "../../interfaces/config";
import * as fse from "fs-extra";
import utils from "../../utils/general-utils";
import * as path from "path";

export function generate(config: IConfig) {
    fse.removeSync(path.join(config.ORM_GENERATE.path.ormWrapper));

    let sFile = '/*** this wrapper class can be used as such (intellisense helpful if you are working in a big project and do not know the data schema well):  ```await Orm.<Model>.findAll()``` ***/' +
                `\nimport { conn } from "../datasources/sequelize"; \n`;

    fse.readdirSync(path.join(config.ORM_GENERATE.path.daos)).forEach((fileName) => {
        let name = fileName.slice(0, -3);
        let daoPath = config.ORM_GENERATE.path.daos;
        let pathSplit = [];
        let daosFolderName = "";

        if (daoPath) {
            pathSplit = daoPath.split("/");
            daosFolderName = pathSplit[pathSplit.length - 1];    
        } else {
            // nothing for now
        }

        if (daosFolderName[0] !== "/") {
            daosFolderName = "/" + daosFolderName;
        }

        sFile += `import { ${utils.capitalizeFirstLetter(name)} } from "..${daosFolderName}/${utils.capitalizeFirstLetter(name)}"; \n`;
    });

    sFile += "\n declare type TupleArray = [Array<any>, Array<any>]; \n\n";
    sFile += "/*** ORM wrapper ***/";
    sFile += "\n export default class Orm { \n";
    // add methods here
    /** raw SQL wrapper*/
    sFile += "\tpublic static query = async (query: string, params = <any>{}): Promise<Array<any>> => { \n" +
                    "\t\tconst results: TupleArray = await conn.query(query, {raw: true, replacements: params }); \n\n" + 
                    "\t\treturn Orm.repackageResults(results); \n" +
            "\t} \n \n";
    sFile += "\t/** if Tuple, make one-d arr; if empty array, return null **/ \n" +
              "\tpublic static repackageResults = (results: TupleArray | null): Array<any> | null => { \n" +
              "\t\tlet retResults; \n" + 
              "\t\tif (Array.isArray(results) && Array.isArray(results[0])) { \n" +
              "\t\t\tretResults = results[0].length !== 0 ? results[0] : null; \n" + 
              "\t\t} \n\n" + 
              "\t\treturn retResults; \n" +
              "\t} \n\n";

              /*
              public static beginTransaction = () => {
                // return conn.transaction();
                return conn.transaction();
              }

              */
    sFile += "\tpublic static beginTransaction = () => {\n" +
             "\t\treturn conn.transaction();\n" +
             "\t} \n\n"


    sFile += "\n\n\t/*** ALL ENTITIES IN ONE LOCATION ***/ \n\n"

    fse.readdirSync(config.ORM_GENERATE.path.daos).forEach((fileName) => {
        let name = fileName.slice(0, -3);

        sFile += `\tpublic static get ${utils.capitalizeFirstLetter(name)}() { \n\t\t return ${utils.capitalizeFirstLetter(name)};\n\t} \n`;
    });

    sFile += "}";

    fse.outputFileSync(config.ORM_GENERATE.path.ormWrapper, sFile, "utf8");
}

