'use strict';

// UTILS
const utils = require('../../../utils');

// CSDR RELATED
const configUtils = require('../../config/config-utils');
const auditUtils = require('../../audit/audit-utils');
const initUtils = require('../../init/init-utils');
const installUtils = require('../../install/install-utils');

// INNER MODULES
const innerCommon = require('./common');


// LOCAL TEST :
// - symlink eUI tools sources to node_modules of standalone pkg folder node_modules to test
// - execute this command on the standalone pkg folder :
// npx @eui/tools release-package-standalone --pkgName zzz-test-package-ui --branch develop --debug --debugNotification --skipCommitsCheck --skipPublish --skipGitUpdates
// npx @eui/tools release-package-standalone --pkgName baep-sample-host-shell-ui --branch develop --debug --debugNotification --skipCommitsCheck --skipPublish --skipGitUpdates --skipInstall

module.exports.run = () => {
  const { dryRun } = utils.tools.getArgs();

  utils.tools.logBanner('Starting UI package stand-alone pipeline');

  // local saved vars
  let newVersion, commitsMetadata;

  // getting the package information - mimics CSDR package config
  const pkg = configUtils.packages.getStandalonePackage();

  // get branches config
  const branches = innerCommon.getBranches();

  return (
    Promise.resolve()
      // RELEASE PACKAGE START

      .then(() => {
        utils.tools.logVersion();
      })

      // Starting the release flow
      .then(() => {
        return innerCommon.initMessage(pkg, branches);
      })

      // CHECK BRANCH VALIDITY
      .then(() => {
        innerCommon.checkBranchValidity(branches);
      })

      // COMMIT METADATA CHECKS
      .then(() => {
        return innerCommon.commitMetadataChecks(pkg);
      })
      .then((metadata) => {
        commitsMetadata = metadata;
      })

      // SPECIFIC INJECTION FOR STANDALONE PKG ROOT FILES
      .then(() => {
        return initUtils.packages.injectStandaloneResources(pkg);
      })

      // INIT PACKAGE CONFIG
      .then(() => {
        // generating angular.json config if not existing
        configUtils.angular.checkAngularConfig();

        // registering package angular config
        configUtils.angular.registerAngularPackage(pkg);
      })

      // INIT ROOT FILES - yarn lock and resolution based on current eUI version of the package
      .then(() => {
        const euiVersion = configUtils.packages.getPackageEuiVersion(pkg);
        return initUtils.global.initRootFilesAndResolutions(euiVersion);
      })

      // INSTALL dependencies by type
      .then(() => {
        utils.tools.logBanner('INSTALL DEPENDENCIES');

        return (
          Promise.resolve()
            .then(() => {
              return installUtils.packages.installDepsStandalone(pkg, branches.isMaster);
            })

            // auditing dependencies
            .then(() => {
              return auditUtils.yarn.audit(pkg);
            })
            .catch((e) => {
              throw e;
            })
        );
      })

      // BUILD PACKAGE
      .then(() => {
        return utils.buildPackage.build(pkg, branches.isMaster, false);
      })

      // EXECUTING SONAR ANALYSIS
      // .then(() => {
      //   return utils.sonar.run(pkg, branches.isMaster);
      // })

      // GENERATE and UPDATE new version
      .then(() => {
        return innerCommon.updateVersion(pkg, commitsMetadata);
      })
      .then((version) => {
        // storing version for later use
        newVersion = version;
      })

      // GENERATE CHANGELOG
      .then(() => {
        utils.tools.logTitle('generating changelog...');
        return utils.changelog.generate(pkg, newVersion, commitsMetadata.commits);
      })

      // WRITE CHANGELOG for MASTER and SUPPORT
      .then((changelogContent) => {
        utils.tools.logTitle('writing changelog...');

        if ((branches.isSupport || branches.isNext || branches.isMaster) && !dryRun) {
          return utils.changelog.writeChangelog(changelogContent, pkg.paths.root);

        } else {
          utils.tools.logInfo('WRITING SKIPPED - (either DRY-RUN or snapshot release) - Actual changelog :');
          console.log(changelogContent);
        }
      })

      // PUBLISH PACKAGE
      .then(() => {
        return utils.publish.publish(pkg);
      })

      // GIT OPERATIONS
      .then(() => {
        return innerCommon.runGitOperations(pkg, newVersion);
      })

      // SEND SUCCESS NOTIFICATION
      .then(() => {
        return innerCommon.sendSuccessNotification(pkg, newVersion, commitsMetadata, false).then(() => {
          return innerCommon.close(pkg);
        });
      })

      // SEND ERROR NOTIFICATION
      .catch((e) => {
        return innerCommon
          .sendErrorNotification(pkg, e, commitsMetadata, false)
          .then(() => {
            return innerCommon.close(pkg);
          })
          .then(() => {
            process.exit(1);
          });
      })
  );
};
