'use strict';

// GLOBAL
const path = require('path');
const execa = require('execa');

// LOCAL
const tools = require('../../tools');
const configUtils = require('../../../csdr/config/config-utils');
const preBuildUtils = require('../../pre-build/pre-build-utils');
const remotesUtils = require('../../remotes/remotes-utils');

let { configuration, baseHref, servePath, dryRun, statsJson, sourceMap, build, skipCompile } = tools.getArgs();


module.exports.build = (pkg, isMaster) => {

  const ng = path.resolve(pkg.paths.repoNodeModules, '@angular', 'cli', 'bin', 'ng');
  const remoteEuiVersion = configUtils.packages.getPackageEuiVersion(pkg, true);
  const pkgName = pkg.name;

  tools.logTitle(`Building remote element : ${pkgName}...`);

  return Promise.resolve()
    .then(() => {
      return preBuildUtils.elements.preBuild(pkg);
    })

    .then(() => {
      tools.logInfo(`Launching element build...`);

      // specific for element
      const versionNumber = remoteEuiVersion.split('.')[0];

      // checking configuration
      if (!configuration) {
        configuration = 'production';
      }

      let args;

      if (versionNumber <= 10) {
        args = ['--max_old_space_size=8096', ng, 'build', pkgName, '--prod'];
      } else {
        args = ['--max_old_space_size=8096', ng, 'build', pkgName];
      }

      if (statsJson) {
        args.push(`--stats-json`);
      }

      args.push(`--configuration=${configuration}`);

      if (baseHref) {
        args.push(`--base-href=${baseHref}`);
      }

      if (servePath) {
        args.push(`--serve-path=${servePath}`);
      }

      if (versionNumber <= 10) {
        const webpackExtraFile = path.join(pkg.paths.root, 'webpack.extra.js');
        if (tools.isFileExists(webpackExtraFile)) {
          args.push(`--extra-webpack-config=${webpackExtraFile}`);
        }
        args.push(`--single-bundle=true`);
      }

      args.push(`--output-hashing=none`);

      if (build) {
        args.push('--progress=false');
      }

      if (sourceMap) {
        args.push('--source-map');
      }

      tools.logInfo(`ng build for configuration : ${configuration}`);

      tools.logInfo(`running Angular BUILD with args: ${args} on`);
      console.log(pkg.paths.root);

      if (!skipCompile) {
        if (build && pkg.msteamsActive) {
          return tools.runNodeScriptProcessOutput(args, pkg.paths.root);

        } else {
          return execa('node', args, { cwd: pkg.paths.root, stdio: 'inherit' });
        }
      }
    })


    .catch((e) => {
      throw e;
    });
};


module.exports.postBuild = (pkg, version) => {
  tools.logTitle('Executing element post-build...');

  const remoteEuiVersion = configUtils.packages.getPackageEuiVersion(pkg);
  const euiVersionNumber = remoteEuiVersion.split('.')[0];

  tools.logInfo(`remote: ${pkg.name} - eUI version : ${remoteEuiVersion}`);

  if (dryRun) {
    tools.logInfo('DRY-RUN...skipping');
  } else {
    return Promise.resolve()
      .then(() => {
        tools.logTitle('ELEMENT POST build');
        tools.logInfo('Copying dist to bundles folder');
        tools.mkdir(path.join(pkg.paths.dist, 'bundles'));

        // remove browser folder for esbuild builds
        const isEsbuild = pkg?.build?.esbuild !== undefined ?? false;

        if (isEsbuild) {
          tools.copydirFiles(path.join(pkg.paths.dist, 'browser'), path.join(pkg.paths.dist));
          tools.remove(path.join(pkg.paths.dist, 'browser'));
        }
        tools.copydir(path.join(pkg.paths.dist), path.join(pkg.paths.dist, 'bundles'));
      })

      .then(() => {
        // Note: it's limited to 18, but it could be applied to 15 / 16 / 17 / 18
        const loadedAsJsModule = euiVersionNumber >= 18;

        if (loadedAsJsModule) {
          return remotesUtils.createEntryJsFile(pkg, path.join(pkg.paths.dist, 'bundles'), euiVersionNumber);
        } else {
          return remotesUtils.concatFiles(pkg, path.join(pkg.paths.dist, 'bundles'), euiVersionNumber);
        }
      })

      .then(() => {
        // Note: it's limited to 18, but it could be applied to 15 / 16 / 17 / 18
        const loadedAsJsModule = euiVersionNumber >= 18;

        const name = loadedAsJsModule ? 'entry' : undefined;
        return remotesUtils.copyPackageJson(pkg, pkg.paths.root, pkg.paths.dist, remoteEuiVersion, name);
      })

      .then(() => {
        tools.logInfo(`Renaming main.js or entry.js file to current version : ${version}`);

        // Note: it's limited to 18, but it could be applied to 15 / 16 / 17 / 18
        const loadedAsJsModule = euiVersionNumber >= 18;

        const name = loadedAsJsModule ? 'entry' : 'main';
        return tools.move(path.join(pkg.paths.dist, 'bundles', `${name}.js`), path.join(pkg.paths.dist, 'bundles', `${name}-` + version + '.js'));
      })

      .then(() => {
        return remotesUtils.emptyIndexHtml(pkg, path.join(pkg.paths.dist, 'bundles'));
      })

      .then(() => {
        return remotesUtils.cleanupUnusedAssets(path.join(pkg.paths.dist, 'bundles', 'assets'), euiVersionNumber);
      })

      .catch((e) => {
        throw e;
      });
  }
};
