const fs = require("fs-extra");
const glob = require("glob");
const path = require("path");
const process = require("process");
//const config = require( './tribes/townconf.js' );
/*const config = {
  unittesting: ["middlewares", "models", "routes", "nationchains"],
};*/

global.__base = __dirname + "/";
const ut = {};
ut.help = `
\x1b[32m###################################\x1b[0m
\x1b[32m### Make it simple Unit Testing ###\x1b[0m
\x1b[32m###################################\x1b[0m
Any file into a folder **/unittest/*.js can be run as a unit test.
Each file have to be independant to test a full process in production as well than in dev.
After each test the data has to be clean up (don't forget that your running test is apply into production). 
Please add explicit research track message to help understand your code and how to debug it.

yarn unittest [-Options] [filtername ]

Options available:
    \x1b[1m-verbose :\x1b[0m add system error to debug. 
    \x1b[1m-publish :\x1b[0m if test valid then push to production server list for propagation. 
    \x1b[1m-help    :\x1b[0m this help. 

filername: any test file name usefull when you just want to test your code under dev

Each unit testing file is structured like
\x1b[100m\x1b[32m
const assert=require('assert');
const any components you require
...
any testing process from create to delete based on assert lib that allow to test if your test expected what it has to be
see https://nodejs.org/api/assert.html  
...
const ut={name:"testing name", run: ()=>{the function to run}};
module.exports=ut;
\x1b[0m

To request any update or change in the code add to your git branch a new file into where you test your modifications /inittest/
We first run your test and check with git diff your code before merge your branch with your inittest

You'll be inform when a new release including your change into apXtrib will be available.
\x1b[7mThanks for improving our democracy tool.\x1b[0m
`;
ut.run = (options) => {
  if (options.filetotest.length == 0)
    console.log(
      "Check your files because no test to run (for more: yarn unittest -help)"
    );
  options.filetotest.forEach((f) => {
    const unittest = require(f);
    console.log("\x1b[34m", `Unittest ${f}`, "\x1b[0m");
    try {
      unittest.run(options);
      console.log("✅", "\x1b[32m", unittest.name, "\x1b[0m");
    } catch (e) {
      console.log(
        "❌",
        "\x1b[41m",
        unittest.name,
        e.stack.split("\n")[0],
        "\x1b[0m"
      );
      if (options.verbose) console.log(e.stack);
    }
  });
};
//get town conf
const infotown = fs.readJsonSync(
  `${__dirname}/adminapi/www/adminapx/conf/setup_xx.json`
);
infotown.dirtown = path.resolve(
  `${__dirname}/../${infotown.townId}-${infotown.nationId}`
);
const conf = fs.readJSONSync(`${infotown.dirtown}/conf.json`);
process.env.dirtown = infotown.dirtown;
const options = { filetotest: [] };
process.argv.slice(2).forEach((arg) => {
  switch (arg.substring(0, 2)) {
    case "-v":
      options.verbose = true;
      break;
    case "-p":
      options.publish = true;
      break;
    case "-h":
      options.active = true;
      options.help = true;
      break;
    default:
      options.active = true;
      conf.api.unittesting.forEach((codefolder) => {
        glob
          .sync(`${__dirname}/api/${codefolder}/**/unittest/${arg}.js`)
          .forEach((f) => {
            if (!options.filetotest.includes(f)) options.filetotest.push(f);
          });
      });
      break;
  }
});
if (!options.active) {
  conf.api.unittesting.forEach((codefolder) => {
    glob
      .sync(`${conf.dirapi}/api/${codefolder}/**/unittest/*.js`)
      .forEach((f) => {
        if (!options.filetotest.includes(f)) options.filetotest.push(f);
      });
  });
  console.log(
    "You can test only some unittest by passing yarn unittest name  where name is a /unittest/name.js file that exist, type 'yarn unittest -help' for more"
  );
  console.log("Looking for unittest folder into ", conf.api.unittesting);
}
options.help ? console.log(ut.help) : ut.run(options);
