'use strict';

const path = require('path');

const tools = require('../tools');
const remotesUtils = require('../remotes/remotes-utils');

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


module.exports.serve = (remote = false) => {

  let { project, configuration, baseHref, servePath, host, proxyConfig, maxSpaceSize, port } = tools.getArgs();

  let pkg;
  if (remote) {
    pkg = configUtils.remotes.getRemote();
  } else {
    pkg = configUtils.packages.getPackage();
  }

  const pkgName = pkg.name;

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

  const ng = path.resolve(pkg.paths.repoNodeModules, '@angular', 'cli', 'bin', 'ng');

  let rootDestPath, destPath;

  if (!project) {
    tools.logInfo('Project paramater must be specified...stopping');
    return;
  }


  return Promise.resolve()
    .then(() => {
      tools.logTitle(`Serving element : ${pkgName}...`);
    })

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

    .then(() => {
      var args;

      if (maxSpaceSize) {
        args = ['--max_old_space_size=4096', ng, 'build', pkgName];
      } else {
        args = [ng, 'build', pkgName];
      }

      const projectConfig = configUtils.projects.getProject(project);

      if (projectConfig.host && projectConfig.virtual) {
        rootDestPath = path.join(process.cwd(), 'hosts', project, 'src', 'assets', 'elements', pkgName);
      } else {
        rootDestPath = path.join(process.cwd(), 'apps', project, 'src', 'assets', 'elements', pkgName);
      }

      destPath = path.join(rootDestPath, 'bundles');

      if (euiVersionNumber <= 10) {
        args.push(`--outputPath=${destPath}`);
        args.push(`--single-bundle=true`);

        if (!configuration) {
          configuration = 'production';
        }
      } else {
        if (!configuration) {
          configuration = 'development';
        }
        args.push(`--output-path=${destPath}`);
      }

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

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

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

      tools.logInfo(`ng build with args ${args}`);

      const spawnSync = require('child_process').spawnSync;
      const output = spawnSync('node', args, { cwd: pkg.paths.root, stdio: 'inherit' });

      if (output.error) {
        throw new Error(JSON.stringify(output));
      }
    })

    .then(() => {
      // remove browser folder for esbuild builds
      const isEsbuild = pkg?.build?.esbuild !== undefined ?? false;

      if (isEsbuild) {
        tools.copydirFiles(path.join(destPath, 'browser'), path.join(destPath));
        tools.remove(path.join(destPath, 'browser'));
        return Promise.resolve();
      } else {
        Promise.resolve();
      }
    })

    .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, destPath, euiVersionNumber);
      } else {
        return remotesUtils.concatFiles(pkg, destPath, 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, rootDestPath, remoteEuiVersion, name);
    })

    .then(() => {
      return remotesUtils.emptyIndexHtml(pkg, destPath);
    })

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