"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.build = build;
exports.buildProject = buildProject;
exports.default = void 0;

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _path = _interopRequireDefault(require("path"));

var _fs = _interopRequireDefault(require("fs"));

var _cliProgress = _interopRequireDefault(require("cli-progress"));

var _utils = require("@corenode/utils");

var _rimraf = _interopRequireDefault(require("rimraf"));

var _vinylFs = _interopRequireDefault(require("vinyl-fs"));

var _through = _interopRequireDefault(require("through2"));

var lib = _interopRequireWildcard(require("./lib"));

var _env$ignore, _env$skip;

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

var env = {};
var builderErrors = Array();

try {
  env = lib.getBuilderEnv();
} catch (error) {
  handleError(error.message);
}

var ignoredSources = (_env$ignore = env.ignore) !== null && _env$ignore !== void 0 ? _env$ignore : [];
var skipedSources = (_env$skip = env.skip) !== null && _env$skip !== void 0 ? _env$skip : [];
var maximunLenghtErrorShow = Number(process.stdout.columns) / 2 - 10;

var packagesPath = _path.default.join(process.cwd(), 'packages');

var isProjectMode = _fs.default.existsSync(packagesPath);

function handleError(err, index, dir) {
  // if (multibar && !packages[index]) {
  //   multibar.remove(tasks[packages[index]])
  // }
  builderErrors.push({
    task: index,
    message: err,
    dir: dir
  });
} //  >> MAIN <<


var outExt = '.js';
var fileExtWatch = ['.js', '.ts'];

function canRead(dir) {
  try {
    _fs.default.accessSync(dir);

    return true;
  } catch (error) {
    return false;
  }
}

function build(_ref) {
  var dir = _ref.dir,
      opts = _ref.opts,
      ticker = _ref.ticker;
  return new Promise(function (resolve, reject) {
    var options = {
      outDir: 'dist',
      agent: 'babel' // default

    };

    if (typeof opts !== "undefined") {
      options = _objectSpread(_objectSpread({}, options), opts);
    }

    var src = _path.default.resolve(dir, `src`);

    var out = _path.default.resolve(dir, options.outDir);

    var sources = [_path.default.join(src, '**/*'), `!${_path.default.join(src, '**/*.test.js')}`];

    function handleTicker() {
      try {
        if (typeof ticker == "function") ticker();
      } catch (error) {// terrible
      }
    }

    if (_fs.default.existsSync(out)) {
      _rimraf.default.sync(out);
    }

    try {
      var stream = _vinylFs.default.src(sources, {
        allowEmpty: true
      }).pipe(_through.default.obj(function (file, codec, callback) {
        function passThrough() {
          handleTicker();
          return callback(null, file);
        }

        if (!_path.default.extname(file.path)) {
          if (canRead(file.path)) {
            return passThrough();
          }

          var oldFilepath = file.path;
          file.path = `${file.path}/index${outExt}`;

          if (_fs.default.existsSync(file.path) && !canRead(file.path)) {
            file.path = `${oldFilepath}/${_path.default.basename(oldFilepath)}`;
          }
        }

        if (skipedSources.includes(_path.default.resolve(file.path))) {
          return passThrough();
        }

        if (fileExtWatch.includes(_path.default.extname(file.path))) {
          lib.agents[options.agent](file.contents, file.path, env).then(function (_output) {
            file.contents = Buffer.from(_output.code);
            file.path = file.path.replace(_path.default.extname(file.path), outExt);
            return passThrough();
          }).catch(function (err) {
            handleError(err.message, 0, file.path);
            return passThrough();
          });
        } else {
          // ignore and return callback for stream file
          handleError(`[${_path.default.extname(file.path)}] type extension not included, ignoring...`, 0, _path.default.basename(file.path));
          return passThrough();
        }
      })).pipe(_vinylFs.default.dest(out));

      stream.on('end', function () {
        return resolve(true);
      });
      stream.on('error', function (err) {
        return reject(err);
      });
    } catch (error) {
      return reject(error);
    }
  });
}

function buildProject(opts) {
  return new Promise(function (resolve, reject) {
    var tasks = {};
    var cliEnabled = opts !== null && opts !== void 0 && opts.cliui ? true : false;
    var multibarEnabled = cliEnabled;
    var builderCount = Number(0);
    var multibar = null;
    var packages = isProjectMode ? _fs.default.readdirSync(packagesPath).filter(function (dir) {
      return dir.charAt(0) !== '.';
    }) : ["./"];

    if (skipedSources.length > 0) {
      skipedSources = skipedSources.map(function (source) {
        return _path.default.resolve(source);
      });
    }

    if (ignoredSources.length > 0) {
      ignoredSources.forEach(function (source) {
        packages = packages.filter(function (pkg) {
          return pkg !== source;
        });
      });
    }

    var dirs = packages.map(function (name) {
      return isProjectMode ? `./packages/${name}` : `${name}`;
    });

    function handleFinish() {
      if (multibarEnabled) {
        multibar.stop();
      }

      if (Array.isArray(builderErrors) && builderErrors.length > 0) {
        var pt = new _utils.prettyTable();
        var headers = ["TASK INDEX", "⚠️ ERROR", "PACKAGE"];
        var rows = [];
        builderErrors.forEach(function (err) {
          var _obj$message, _obj$dir, _obj$task, _obj$message2, _obj$dir2;

          var obj = _objectSpread({}, err);

          if ((obj === null || obj === void 0 ? void 0 : (_obj$message = obj.message) === null || _obj$message === void 0 ? void 0 : _obj$message.length) > maximunLenghtErrorShow) {
            obj.message = String(obj.message).slice(0, maximunLenghtErrorShow - 3) + "...";
          }

          if ((obj === null || obj === void 0 ? void 0 : (_obj$dir = obj.dir) === null || _obj$dir === void 0 ? void 0 : _obj$dir.length) > maximunLenghtErrorShow) {
            obj.dir = String(obj.dir).slice(0, maximunLenghtErrorShow - 3) + "...";
          }

          rows.push([(_obj$task = obj.task) !== null && _obj$task !== void 0 ? _obj$task : "UNTASKED", (_obj$message2 = obj.message) !== null && _obj$message2 !== void 0 ? _obj$message2 : "Unknown error", (_obj$dir2 = obj.dir) !== null && _obj$dir2 !== void 0 ? _obj$dir2 : "RUNTIME"]);
        });
        pt.create(headers, rows);

        try {
          var dumpLogger = require('@corenode/verbosity-dump-module').default;

          dumpLogger({
            level: "warn",
            stack: "builder"
          }).info(`⚠️ BUILDER ERRORS\n ${JSON.stringify(builderErrors, null, 2)}`);
        } catch (error) {
          // ironically terrible
          console.log(`⚠️🆘  Error dumping errors >> ${error}`);
        }

        console.log(`\n⚠️  ERRORS / WARNINGS DURING BUILDING`);
        pt.print();
      }

      resolve();
    }

    function handleTicker(index) {
      if (multibarEnabled) {
        tasks[packages[index]].increment(1);
      }
    }

    function handleThen(index) {
      if (typeof index == "undefined") {
        return reject(`handleThen index not defined!`);
      }

      builderCount += 1;

      if (multibarEnabled) {
        var task = tasks[packages[index]];
        var currentValue = task.value;
        var totalValue = task.total;

        if (currentValue != totalValue) {
          task.setTotal(currentValue);
        }
      }

      if (builderCount == packages.length - 1) {
        handleFinish();
      }
    } // >> MAIN <<


    try {
      if (cliEnabled) {
        if (multibarEnabled) {
          multibar = new _cliProgress.default.MultiBar({
            forceRedraw: false,
            stopOnComplete: true,
            barsize: 20,
            clearOnComplete: false,
            hideCursor: true,
            format: '[{bar}] {percentage}% | {filename} | {value}/{total}'
          }, _cliProgress.default.Presets.shades_grey);
        }
      }
    } catch (error) {
      handleError(error, "UNTASKED", "CLI INIT");
    }

    dirs.forEach(function (dir, index) {
      try {
        if (multibar && multibarEnabled) {
          var packagePath = _path.default.resolve(process.cwd(), `${dir}/src`);

          var sources = lib.listAllFiles(packagePath).length;
          tasks[packages[index]] = multibar.create(sources, 0);
          tasks[packages[index]].update(0, {
            filename: packages[index]
          });
        }
      } catch (error) {
        console.log(error); // terrible
      } // start builder


      build({
        dir,
        opts,
        ticker: function ticker() {
          return handleTicker(index);
        }
      }).then(function (done) {
        handleThen(index);
      }).catch(function (err) {
        if (Array.isArray(err)) {
          err.forEach(function (error) {
            handleError(error.message, index, dir);
          });
        } else {
          handleError(`${err}`, index, dir);
        }
      });
    });
  });
}

var _default = buildProject;
exports.default = _default;