'use strict';

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

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

// CSDR RELATED
const initUtils = require('../../init/init-utils');
const configUtils = require('../../config/config-utils');
const metadataUtils = require('../../metadata/metadata-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-remote-standalone --remoteName zzz-test-remote-eui18 --envTarget DEV --debug --debugNotification --debugGitUpdates --skipPublish --skipGitUpdates --skipNotification


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

    const { remoteName, envTarget } = utils.tools.getArgs();

    if (!remoteName) {
      throw new Error('remoteName not provided as pipeline argument');
    }

    if (!envTarget) {
      throw new Error('envTarget not provided as pipeline argument');
    }


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

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

    return Promise.resolve()
      // START PIPELINE
      .then(() => {
        utils.tools.logVersion();
      })

      // CLONE CONFIG REPOSITORY - for gathering central remotes config
      .then(() => {
        return configUtils.global.cloneConfig();
      })

      // GET REMOTE OBJECT
      .then(() => {
        pkg = configUtils.remotes.getRemote(remoteName, true);
      })

      // GENERATE THE VURTUAL REMOTE
      .then(() => {
        return initUtils.remotes.generateVirtualRemote(remoteName, false, true);
      })

      // INITIATE MESSAGE STACK
      .then(() => {
        return innerCommon.initMessage(pkg, branches, envTarget);
      })

      // CLONE METADATA FOR remote build history
      .then(() => {
        return metadataUtils.common.cloneMetadataRepoStandalone();
      })

      // INSTALL dependencies by type
      .then(() => {
        return installUtils.buildPackage.installRemote(pkg, envTarget);
      })
      .then((compositeDeps) => {
        // storing for later use
        pkgCompositeDeps = compositeDeps;
      })

      // BUILD THE REMOTE
      .then(() => {
        return utils.buildPackage.build(pkg, true);
      })

      // UPDATE VERSION
      .then(() => {
        return innerCommon.updateVersion(pkg, null, envTarget);
      })
      .then((version) => {
        // storing version for later use
        newVersion = version;
      })

      .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);
      })


      // STORING CENTRALIZED METADATA
      .then(() => {
        // get run duration
        const duration = utils.pipeline.getTimerDuration();

        // store envs + versions for virtual remotes
        return metadataUtils.remotePackage.storeMetadata(pkg, newVersion, pkgCompositeDeps, duration, envTarget);
      })


      // // GENERATE DIFF REPORT
      // .then(() => {
      //   let metadata;

      //   if (envTarget !== 'DEV') {
      //     return Promise.resolve()
      //       .then(() => {
      //         return metadataUtils.remoteHistory.generateDiffCommitsMetadataReport(pkg, envTarget);
      //       })
      //       .then((output) => {
      //         metadata = output;
      //       })
      //       .then(() => {
      //         return utils.notification.package.sendPackageDiffReportMessage(
      //           pkg,
      //           metadata.diffsMetadata
      //         );
      //       })
      //       .then(() => {
      //         return metadataUtils.remoteHistory.storeMetadataHistory(pkg, metadata, newVersion);
      //       })
      //       .then(() => {
      //         if (metadata.commitsMetadata && metadata.commitsMetadata.issues) {
      //           return metadataUtils.remoteHistory.generatePipelineIssuesList(metadata.commitsMetadata.issues);
      //         }
      //       })
      //       .catch((e) => {
      //         utils.tools.logError('Error generating diffs report for current remote processed :');
      //         console.log(e);
      //       })
      //     }
      // })


      // COMMITING METADATA
      .then(() => {
        return innerCommon.commitMetadata(pkg, newVersion);
      })


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

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

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