var libBabel = require("@babel/core");

fcf.module({
  name: "fcf:NSystem/babel.js",
  dependencies: ["fcf:NSystem/NPackage/tools.js"],
  module: function(toolsPackages){
    var Namespace = fcf.prepareObject(fcf, "packages/fcf/NTools");

    class Babel {
      constructor(){
      }

      isNeedCompile(a_userAgentString){

        function getVersion(a_string, a_start){
          let result = "";
          let cn0 = "0".charCodeAt(0);
          let cn9 = "9".charCodeAt(0);
          for(let i = a_start; i < a_string.length; ++i){
            let cn = a_string.charCodeAt(i);
            if ((cn >= cn0 && cn <= cn9) || a_string[i] == "."){
              result += a_string[i];
            } else {
              break;
            }
          }
          return result;
        }

        function getBrowser(a_userAgentString){
          let checkstr = undefined;
          let checkstr1 = undefined;
          let checkstr2 = undefined;
          let pos = undefined;
          let pos1 = undefined;
          let pos2 = undefined;

          if (typeof a_userAgentString !== "string"){
            return {
              browser: undefined,
              version: undefined
            }
          }

          checkstr = "Firefox/";
          checkstr2 = "Mobile";
          pos = a_userAgentString.indexOf(checkstr);
          pos2 = a_userAgentString.indexOf(checkstr2);
          if (pos != -1 && pos2 != -1){
            pos += checkstr.length;
            pos2 += checkstr2.length;
            return {
              browser: "firefox-mobile",
              version: getVersion(a_userAgentString, pos)
            }
          }

          checkstr = "Chrome/";
          checkstr2 = " Mobile ";
          pos = a_userAgentString.indexOf(checkstr);
          pos2 = a_userAgentString.indexOf(checkstr2);
          if (pos != -1 && pos2 != -1){
            pos += checkstr.length;
            pos2 += checkstr2.length;
            return {
              browser: "chrome-mobile",
              version: getVersion(a_userAgentString, pos)
            }
          }

          checkstr = "Safari/";
          checkstr1 = "Mobile";
          checkstr2 = "Version/";
          pos = a_userAgentString.indexOf(checkstr);
          pos1 = a_userAgentString.indexOf(checkstr1);
          pos2 = a_userAgentString.indexOf(checkstr2);
          if (pos != -1 && pos1 != -1 && pos2 != -1){
            pos += checkstr.length;
            pos2 += checkstr2.length;
            return {
              browser: "safari-mobile",
              version: getVersion(a_userAgentString, pos2)
            }
          }

          checkstr = "Safari/";
          checkstr2 = "Version/";
          pos = a_userAgentString.indexOf(checkstr);
          pos2 = a_userAgentString.indexOf(checkstr2);
          if (pos != -1 && pos2 != -1){
            pos += checkstr.length;
            pos2 += checkstr2.length;
            return {
              browser: "safari",
              version: getVersion(a_userAgentString, pos2)
            }
          }

          checkstr = "Edg/";
          pos = a_userAgentString.indexOf(checkstr);
          if (pos != -1){
            pos += checkstr.length;
            return {
              browser: "edge",
              version: getVersion(a_userAgentString, pos)
            }
          }

          checkstr = "OPR/";
          pos = a_userAgentString.indexOf(checkstr);
          if (pos != -1){
            pos += checkstr.length;
            return {
              browser: "opera",
              version: getVersion(a_userAgentString, pos)
            }
          }

          checkstr = "Firefox/";
          pos = a_userAgentString.indexOf(checkstr);
          if (pos != -1){
            pos += checkstr.length;
            return {
              browser: "firefox",
              version: getVersion(a_userAgentString, pos)
            }
          }

          checkstr = "Chrome/";
          pos = a_userAgentString.indexOf(checkstr);
          if (pos != -1){
            pos += checkstr.length;
            return {
              browser: "chrome",
              version: getVersion(a_userAgentString, pos)
            }
          }

          return {
              browser: undefined,
              version: undefined
            }
        }

        let browser = getBrowser(a_userAgentString);

        if (!browser.browser || !browser.version)
          return true;

        if (browser.browser == "chrome" && parseInt(browser.version) >= 58)
          return false;
        if (browser.browser == "chrome-mobile" && parseInt(browser.version) >= 58)
          return false;
        if (browser.browser == "firefox" && parseInt(browser.version) >= 52)
          return false;
        if (browser.browser == "firefox-mobile" && parseInt(browser.version) >= 52)
          return false;
        if (browser.browser == "edge" && parseInt(browser.version) >= 13)
          return false;
        if (browser.browser == "opera" && parseInt(browser.version) >= 45)
          return false;
        if (browser.browser == "safari" && toolsPackages.cmpVersion(browser.version, "10.1") >= 0)
          return false;
        if (browser.browser == "safari-mobile" && toolsPackages.cmpVersion(browser.version, "10.3") >= 0)
          return false;
        return true;
      }

      getCompileFilePath(a_path){

      }

      prepareFile(a_path){
        return fcf.actions()
      }

      async transform(a_code){
        return fcf.actions()
        .then((a_res, a_act)=>{
          libBabel.transform(
            a_code,
            {
              code: true,
              sourceType: "script",
              root: fcf.getPath(":"),
              cwd: fcf.getPath(":"),
              presets: [],
              plugins: [
                "@babel/plugin-transform-block-scoped-functions",
                "@babel/plugin-transform-arrow-functions",
                "@babel/plugin-transform-duplicate-keys",
                "@babel/plugin-transform-block-scoping",
                "@babel/plugin-transform-classes",
                "@babel/plugin-transform-for-of",
                "@babel/plugin-transform-destructuring",
                "@babel/plugin-transform-computed-properties",
                "@babel/plugin-transform-function-name",
                "@babel/plugin-transform-instanceof",
                "@babel/plugin-transform-object-super",
                "@babel/plugin-transform-literals",
                "@babel/plugin-transform-parameters",
                "@babel/plugin-transform-shorthand-properties",
                "@babel/plugin-transform-spread",
                "@babel/plugin-transform-sticky-regex",
                "@babel/plugin-transform-template-literals",
                "@babel/plugin-transform-typeof-symbol",
                "@babel/plugin-transform-unicode-regex",
                "@babel/plugin-transform-async-to-generator",
                "@babel/plugin-transform-regenerator",
                "@babel/plugin-transform-property-mutators",
                "@babel/plugin-transform-member-expression-literals",
              ],
            },
            (a_error, a_result)=>{
              if (a_error){
                a_act.error(a_error);
                return
              }
              a_act.complete(a_result.code);
            }
          );
        })
      }

      transformSync(a_code){
        let result = libBabel.transformSync(
            a_code,
            {
              code: true,
              sourceType: "script",
              root: fcf.getPath(":"),
              cwd: fcf.getPath(":"),
              presets: [],
              plugins: [
                "@babel/plugin-transform-block-scoped-functions",
                "@babel/plugin-transform-arrow-functions",
                "@babel/plugin-transform-duplicate-keys",
                "@babel/plugin-transform-block-scoping",
                "@babel/plugin-transform-classes",
                "@babel/plugin-transform-for-of",
                "@babel/plugin-transform-destructuring",
                "@babel/plugin-transform-computed-properties",
                "@babel/plugin-transform-function-name",
                "@babel/plugin-transform-instanceof",
                "@babel/plugin-transform-object-super",
                "@babel/plugin-transform-literals",
                "@babel/plugin-transform-parameters",
                "@babel/plugin-transform-shorthand-properties",
                "@babel/plugin-transform-spread",
                "@babel/plugin-transform-sticky-regex",
                "@babel/plugin-transform-template-literals",
                "@babel/plugin-transform-typeof-symbol",
                "@babel/plugin-transform-unicode-regex",
                "@babel/plugin-transform-async-to-generator",
                "@babel/plugin-transform-regenerator",
                "@babel/plugin-transform-property-mutators",
                "@babel/plugin-transform-member-expression-literals",
              ],
            }
          );
        return result.code;
      }
    };

    Namespace.babel = new Babel();

    return Namespace.babel;
  }
});
