const bcrypt = require("bcrypt");
const fs = require("fs-extra");
const glob = require("glob");
const moment = require("moment");
const jwt = require("jwt-simple");
const UUID = require("uuid");
const conf = require(`${process.env.dirtown}/conf.json`);
const Checkjson = require(`./Checkjson.js`);
const Odmdb = require("./Odmdb.js");

const Towns = {};

Towns.create = () => {
  // Create a new town from conf (generate in apxtribe.js if town not already exist in the server)
  console.log(
    `RUNNING A NEW SETUP with nation ${conf.nationId} and town ${conf.townId} to be accessible in dns http://${conf.dns}`
  );
  const initconf = fs.readJSONSync(
    `${conf.dirapi}/adminapi/www/adminapx/initconf.json`
  );
  // Synchronize nationchains/
  const { updateobjectsfromfreshesttown } = require("./api/models/Nations.js");
  updateobjectsfromfreshesttown(initconf.towns, {
    pagans: "alias_all.json",
    towns: "townId_all.json",
    nations: "nationId_all.json",
  });

  initconf.dirapi = conf.dirapi;
  initconf.dirtown = conf.dirtown;
  initconf.nationId = conf.nationId;
  initconf.townId = conf.townId;
  initconf.sudoerUser = process.env.USER;
  if (!initconf.dns.includes(conf.dns)) {
    initconf.dns.push(conf.dns);
  }
  initconf.nginx.include.push(`${initconf.dirapi}/adminapi/www/nginx_*.conf`);
  initconf.nginx.include.push(`${initconf.dirtown}/tribes/**/www/nginx_*.conf`);
  initconf.nginx.logs = `${initconf.dirtown}/logs/nginx/adminapx`;
  fs.ensureDirSync(`${initconf.dirtown}/logs/nginx`);
  fs.ensureDirSync(`${initconf.dirtown}/tmp/tokens`);

  initconf.nginx.website = "adminapx";
  initconf.nginx.fswww = `${initconf.dirapi}/adminapi/www`;
  initconf.nginx.pageindex = "index_en.html";
  const { exec } = require("child_process");
  exec(
    `sudo chown -R ${process.env.USER}:${process.env.USER} /etc/nginx`,
    (error, stdout, stderr) => {
      if (error) {
        console.log("\x1b[42m", error, stdout, stderr, "x1b[0m");
        console.log(
          `impossible to change owner of /etc/nginx by ${initconf.sudoerUser}:${initconf.sudoerUser}`
        );
        fs.removeSync(initconf.dirtown);
        process.exit();
      } else {
        console.log(
          `successfull sudo chown -R ${process.env.USER}:${process.env.USER} /etc/nginx`
        );
      }
    }
  );
  // create town env
  fs.outputJsonSync(`${initconf.dirtown}/conf.json`, initconf, { space: 2 });
  const nginxconf = fs.readFileSync(
    "./adminapi/www/adminapx/conf/nginx.conf.mustache",
    "utf8"
  );
  const proxyparams = fs.readFileSync(
    "./adminapi/www/adminapx/conf/nginxproxyparams.mustache",
    "utf8"
  );
  const websiteconf = fs.readFileSync(
    "./adminapi/www/adminapx/conf/nginxmodelwebsite.conf.mustache",
    "utf8"
  );

  // saved and change nginx conf
  if (!fs.existsSync("/etc/nginx/nginxconf.saved")) {
    fs.moveSync("/etc/nginx/nginx.conf", "/etc/nginx/nginxconf.saved");
    console.log(
      "your previous /etc/nginx/nginx.conf was backup in  /etc/nginx/nginxconf.saved"
    );
  }
  fs.outputFileSync(
    "/etc/nginx/nginx.conf",
    mustache.render(nginxconf, initconf),
    "utf8"
  );
  fs.outputFileSync(
    "/etc/nginx/proxy_params",
    mustache.render(proxyparams, initconf),
    "utf8"
  );
  fs.outputFileSync(
    `${initconf.dirapi}/adminapi/www/nginx_adminapx.conf`,
    mustache.render(websiteconf, initconf),
    "utf8"
  );
  exec(initconf.nginx.restart, (error, stdout, stderr) => {
    if (error) {
      console.log("\x1b[42m", error, stdout, stderr, "x1b[0m");
      //@todo supprimer la derniere config nginx et relancer
      fs.moveSync("/etc/nginx/nginxconf.saved", "/etc/nginx/nginx.conf");
      console.log("Restart yarn dev with correct parameter");
      // cleanup
      fs.removeSync(initconf.dirtown);
    } else {
      //@TODO à finaliser en test sur machien pour creation de nouvelles villes
      // add town in nationchains
      const gettown = Odmdb.get(`${initconf.dirapi}/nationchains`, "towns", [
        initconf.townId,
      ]);
      if (gettown.data[initconf.townId] == "notfound") {
        Odmdb.create(
          `${initconf.dirapi}/nationschains`,
          "towns",
          {
            townId: initconf.townId,
            nationId: initconf.nationId,
            dns: initconf.dns,
            IP: "127.0.0.1",
            status: "unchain",
            tribes: [],
          },
          false
        );
      } else if (gettown.data[initconf.townId].dns !== initconf.dns) {
        //reinstallation d'une town sur un autre serveur maj du dns , l'ip le status et les tribes se mettent à jour via l'interface
        const updtown = Odmdb.update(
          `${initconf.dirapi}/nationchains`,
          "towns",
          { dns: initconf.dns },
          initconf.townId
        );
      }
      console.log(`ready to use http://${initconf.dns}`);
    }
  });
};

Towns.changeowner = async (newowner, requestby) => {
  /**
   *
   */
  if (!fs.existsSync(`./nationchains/pagans/itm/${newowner}.json`)) {
    return {
      status: 404,
      ref: "towns",
      msg: "newownerdoesnotexist",
      data: { alias: newowner },
    };
  }
  if (!conf.mayorId || conf.mayorId == requestby) {
    // update object town + town/conf.json + setup_xx.json
    const gettown = Odmdb.get(`${conf.dirapi}/nationchains`, "towns", [
      conf.townId,
    ]);
    console.log(`before town: ${conf.townId}`, gettown);
    if (gettown.data[conf.townId] == "notfound") {
      return {
        status: 404,
        ref: "towns",
        msg: "townIdnotfound",
        data: { townId: conf.townId },
      };
    }
    gettown.data[conf.townId].mayorId = newowner;
    const objup = await Odmdb.update(
      `${conf.dirapi}/nationchains`,
      "towns",
      gettown.data[conf.townId],
      conf.townId
    );
    //update the itm town
    if (objup.status != 200) {
      return objup;
    }
    console.log(`after town update: ${conf.townId}`, gettown);

    conf.mayorId = newowner;
    fs.outputJsonSync(`${process.env.dirtown}/conf.json`, conf);
    const setup = fs.readJSONSync(
      `${conf.dirapi}/adminapi/www/adminapx/conf/setup_xx.json`
    );
    conf.mayorId = newowner;
    //update the setup file for webapp adminapi
    fs.outputJsonSync(
      `${conf.dirapi}/adminapi/www/adminapx/conf/setup_xx.json`,
      setup
    );
    return {
      status: 200,
      ref: "towns",
      msg: "newownerchangesuccess",
      data: { alias: newowner },
    };
  }
  return {
    status: 403,
    ref: "towns",
    msg: "notallow",
    data: { newowner, currentowner: conf.mayorId },
  };
};

module.exports = Towns;
