'use strict';

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

// LOCAL
const tools = require('../../utils/tools');
const configUtils = require('../config/config-utils');

// ARGS
const { dryRun } = tools.getArgs();


module.exports.storeMetadata = (pkg, pkgVersion, pkgCompositeDeps, duration, envTarget) => {
  tools.logTitle('Storing central and package metadata...');

  return Promise.resolve()
    .then(() => {
      return storeMetadataVersions(pkg, pkgVersion, pkgCompositeDeps, duration, envTarget);
    })

    .then(() => {
      return storeMetadataEnvs(pkg, pkgVersion, pkgCompositeDeps, envTarget);
    })

    .then(() => {
      tools.logSuccess();
    })

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

module.exports.getMetadataVersions = (pkg) => {
  let DEVOPS_METADATA_PATH;

  if (pkg.standalone) {
    DEVOPS_METADATA_PATH = configUtils.global.getConfigOptionsStandalone().DEVOPS_METADATA_PATH;
  } else {
    DEVOPS_METADATA_PATH = configUtils.global.getConfigOptions().DEVOPS_METADATA_PATH;
  }


  return Promise.resolve()
    .then(() => {
      if (!DEVOPS_METADATA_PATH) {
        throw new Error(`Devops metadata folder ${DEVOPS_METADATA_PATH} NOT FOUND`) ;
      }

      return tools.getJsonFileContent(path.join(DEVOPS_METADATA_PATH, pkg.devopsVersionsMetadataFile));
    })
    .catch((e) => {
      throw e;
    })
}


const storeMetadataVersions = (pkg, pkgVersion, pkgCompositeDeps, duration, envTarget) => {
  return Promise.resolve()
    .then(() => {
      tools.logInfo('Storing package version history metadata...');

      let configOptions;

      if (pkg.standalone) {
        configOptions = configUtils.global.getConfigOptionsStandalone();
      } else {
        configOptions = configUtils.global.getConfigOptions();
      }


      let generatedMetadata = {};
      let versions = [];

      let pkgMetadataFile = path.join(configOptions.DEVOPS_METADATA_PATH, pkg.devopsVersionsMetadataFile);
      if (pkg.backend) {
        pkgMetadataFile = path.join(pkg.paths.root, 'package-versions-metadata.json');
      }

      if (tools.isFileExists(pkgMetadataFile)) {
        generatedMetadata = require(pkgMetadataFile);
        versions = generatedMetadata.versions;
      }

      const newVersionMetadata = {
        name: pkg.name,
        version: pkgVersion,
        date: moment(new Date()).format("YYYYMMDD-HH:mm"),
        npmPkg: pkg.npmPkg,
        duration: duration,
        envTarget: envTarget,
      };

      if (pkg.remote) {
        tools.logInfo('Writing remote composite dependencies');
        newVersionMetadata.dependencies = pkgCompositeDeps;
      }
      console.log(newVersionMetadata);
      versions.push(newVersionMetadata);
      generatedMetadata.versions = versions;

      tools.logInfo(`Write metadata on ${pkgMetadataFile}`);

      if (dryRun) {
        tools.logInfo('DRY RUN...outputing newVersionMetadata');

      } else {
        tools.writeJsonFileSync(pkgMetadataFile, generatedMetadata);
      }
    })

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



const getPackageVersionsJson = (pkg) => {
  if (!pkg) {
    tools.logWarning('provided pkg is empty...skipping');
    return;
  }

  tools.logInfo(`Getting package versions for : ${pkg.name}...`);

  const configOptions = configUtils.global.getConfigOptions();
  const pkgMetadataFile = path.join(configOptions.DEVOPS_METADATA_PATH, pkg.devopsVersionsMetadataFile);

  tools.logInfo(`from ${pkgMetadataFile}`);

  return tools.getJsonFileContent(pkgMetadataFile);
}

module.exports.getPackageVersionsLatest = (pkg) => {
  const pkgVersionsJson = getPackageVersionsJson(pkg);

  if (pkgVersionsJson && pkgVersionsJson.versions) {
    return pkgVersionsJson.versions.filter((v) => {
      return v.version.indexOf('snapshot') === -1;
    });
  }
}


module.exports.storeMetadataAssets = (pkg, pkgCompositeDeps) => {
  return Promise.resolve()
    .then(() => {
      const pkgMetadataFile = path.join(pkg.paths.dist, 'bundles', 'package-metadata.json');
      const pkgMetadataRootFile = path.join(pkg.paths.root, 'package-metadata.json');

      const pkgMetadata = {
        dependencies: pkgCompositeDeps,
        buildDate: moment(new Date()).format("DD/MM/YYYY HH:mm"),
      };

      if (dryRun) {
        tools.logInfo('DRY RUN...outputing metadataAssets');
        console.log(pkgMetadata);

      } else {
        tools.logInfo(`Creating ${pkgMetadataFile}`);
        console.log(pkgMetadata);

        tools.writeJsonFileSync(pkgMetadataFile, pkgMetadata);
        tools.writeJsonFileSync(pkgMetadataRootFile, pkgMetadata);
      }
    })

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


module.exports.getMetadataEnvs = (pkg) => {
  tools.logInfo('metadata.remotePackage.getMetadataEnvs');

  let DEVOPS_METADATA_PATH;

  if (pkg.standalone) {
    DEVOPS_METADATA_PATH = configUtils.global.getConfigOptionsStandalone().DEVOPS_METADATA_PATH;
  } else {
    DEVOPS_METADATA_PATH = configUtils.global.getConfigOptions().DEVOPS_METADATA_PATH;
  }

  return Promise.resolve()
    .then(() => {
      if (DEVOPS_METADATA_PATH) {
        return tools.getJsonFileContent(path.join(DEVOPS_METADATA_PATH, pkg.devopsEnvsMetadataFile));
      } else {
        return;
      }
    })
    .catch((e) => {
      throw e;
    })
}



const storeMetadataEnvs = (pkg, newVersion, metadata, envTarget) => {
  const releaseDate = moment(new Date()).format("DD/MM/YYYY HH:mm");
  const infos = `${newVersion} - ${releaseDate}`;

  let DEVOPS_METADATA_PATH;

  if (pkg.standalone) {
    DEVOPS_METADATA_PATH = configUtils.global.getConfigOptionsStandalone().DEVOPS_METADATA_PATH;
  } else {
    DEVOPS_METADATA_PATH = configUtils.global.getConfigOptions().DEVOPS_METADATA_PATH;
  }


  return Promise.resolve()
    .then(() => {
      tools.logInfo('Storing package environment metadata...');

      const metadataFile = path.join(DEVOPS_METADATA_PATH, pkg.devopsEnvsMetadataFile);

      let generatedMetadata;
      if (tools.isFileExists(metadataFile)) {
        generatedMetadata = require(metadataFile);
      } else {
        generatedMetadata = {};
      }

      generatedMetadata[envTarget] = {
        version: newVersion,
        releaseDate: releaseDate,
        infos: infos,
        dependencies: metadata
      };

      if (dryRun) {
        tools.logInfo('DRY RUN...storing envs metadata');
        console.log(generatedMetadata[envTarget]);

      } else {
        tools.logInfo(`Writing envs metadata to ${metadataFile}`);
        tools.writeJsonFileSync(metadataFile, generatedMetadata);
      }
    })

    .then(() => {
      tools.logSuccess();
    })

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