'use strict';

// TO BE DEPRECATED AND REMOVES ONCE ALL REMOTES HAVE BEEN MIGRATED TO VIRTUAL
// REMAINING "OLD" REMOTES are located only in the .csdr/.euirc-csdr-packages.json file
// the new ones / virtual are only located in the .csdr/.euirc-csdr-remotes.json

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

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

// CSDR RELATED
const configUtils = require('../../config/config-utils');
const metadataUtils = require('../../metadata/metadata-utils');
const installUtils = require('../../install/install-utils');

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


module.exports.run = () => {
    utils.tools.logBanner('Starting UI pipeline');

    // fetching package from config based on default arg
    const pkg = configUtils.packages.getPackage();

    // checking if the package can be retrieved from args
    if (!pkg.name) {
      utils.tools.logError('ERROR : "package" NOT PROVIDED as argument !!!');
      process.exit(1);
    }

    // Get branches flags
    const branches = innerCommon.getBranches();

    // Get envTarget (used by remotes)
    const envTarget = innerCommon.getEnvTarget();

    // local saved vars
    let newVersion, pkgMetadata, pkgCompositeDeps;


    return Promise.resolve()

      // RELEASE PACKAGE START
      .then(() => {
        return innerCommon.init(pkg, envTarget);
      })

      // FOR UI and REMOTES clone metadata repositories
      .then(() => {
        return innerCommon.cloneMetadataRepos(pkg);
      })

      // PRE-RELEASE & COMMON CHECKS
      .then(() => {
        return innerCommon.preReleaseChecks(pkg);
      })

      // FETCHING COMMITS METADATA
      .then(() => {
        return metadataUtils.commit.getMetadata(pkg);
      })
      .then((metadata) => {
        pkgMetadata = metadata;
      })

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


      // EXECUTING PRE BUILD SCRIPT IF AVAILABLE
      .then(() => {
        return innerCommon.preBuild(pkg);
      })


      // INSTALL dependencies by type
      .then(() => {
        return Promise.resolve()
          // FETCHING CURRENT PACKAGES & INSTALL
          .then(() => {
            // install the dependencies for current package build
            return installUtils.buildPackage.installRemote(pkg, envTarget);
          })
          .then((compositeDeps) => {
            // storing for later use
            pkgCompositeDeps = compositeDeps;
          })
          .catch((e) => {
            throw e;
          })
      })


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

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


      // EXECUTING GLOBAL POST BUILD
      .then(() => {
        return innerCommon.postBuild(pkg, newVersion);
      })


      // STORING METADATA ASSETS
      .then(() => {
        return innerCommon.storeMetadataAssets(pkg, pkgCompositeDeps);
      })


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


      // EXECUTING POST PUBLISH SCRIPT IF AVAILABLE
      .then(() => {
        return utils.publish.postPublish(pkg);
      })


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


      // EXPORT ADDITIONAL PIPELINE VARIABLES
      .then(() => {
        return innerCommon.exportPipelineVariables(pkg);
      })


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

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