'use strict';

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

// INNER MODULES
const innerCommon = require('./common');
const innerRemotes = require('./remotes');
const innerProjects = require('./projects');
const innerPackages = require('./packages');

module.exports.installPackage = (pkgName) => {
  const pkg = configUtils.packages.getPackage(pkgName, false, true);

  return Promise.resolve()
    .then(() => {
      if (pkg.remote) {
        return innerRemotes.installDeps(pkg);
      } else {
        return innerPackages.installDeps(null, pkg);
      }
    })

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


module.exports.installRemote = (remoteName) => {

  const remote = configUtils.remotes.getRemote(remoteName);

  return Promise.resolve()
    .then(() => {
      return innerRemotes.installDeps(remote);
    })

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


module.exports.install = (providedDeps) => {
  let finalDeps = {}, resolvedDeps = {}, remoteDeps = {};

  if (providedDeps) {
    resolvedDeps = providedDeps;
  }

  return Promise.resolve()
    // getting internal packages deps - cloned locally
    .then(() => {
      return innerPackages.getLocalPackagesDeps();
    })
    .then((deps) => {
      resolvedDeps = {...resolvedDeps, ...deps};
    })

    // Getting internal packages deps - project cloned locally
    .then(() => {
      return innerPackages.getLocalPackagesCompositeDeps();
    })
    .then((deps) => {
      resolvedDeps = {...resolvedDeps, ...deps};
    })

    // Getting internal packages deps - project cloned locally
    .then(() => {
      return innerProjects.getLocalProjectsDeps();
    })
    .then((deps) => {
      resolvedDeps = {...resolvedDeps, ...deps};
    })

    // getting internal projects fixed deps if any
    .then(() => {
      return innerProjects.getLocalProjectsFixedDeps();
    })
    .then((deps) => {
      resolvedDeps = {...resolvedDeps, ...deps};
    })

    // getting internal projects remotes deps if any
    .then(() => {
      return innerProjects.getLocalProjectsRemoteDeps();
    })
    .then((deps) => {
      remoteDeps = deps; // storing for remote import usage
      resolvedDeps = {...resolvedDeps, ...deps};
    })



    // Parse dependencies against carrets ones for projects
    .then(() => {
      const fixedDeps = configUtils.global.getConfigOptions().NPM_FIXED_DEPENDENCIES;

      const configDeps = { ...resolvedDeps, ...fixedDeps };

      if (configUtils.global.isCsdr()) {
        return innerCommon.getResolvedCarretDeps(configDeps, false, true);
      } else {
        return innerCommon.getResolvedCarretDepsStandalone(configDeps, false, true);
      }

    })


    // Install dependencies
    .then((updatedDeps) => {
      finalDeps = updatedDeps;

      return innerCommon.installDeps(updatedDeps);
    })

    // Import remotes into local projects
    .then(() => {
      return innerProjects.importLocalProjectsRemotes(remoteDeps);
    })

    // checking remotes
    .then(() => {
      return innerRemotes.installDeps();
    })

    .then(() => {
      return finalDeps;
    })

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