'use strict';

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

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

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

module.exports.run = (args) => {
  return Promise.resolve()
    .then(() => {
      if (args.custom) {
        return initConfigCustom(args);
      } else if (args.projectsGroup) {
        return initConfigProjectsGroup(args.projectsGroup, args.euiVersion);
      } else {
        return initConfigCore(args);
      }
    })

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

const initConfigCustom = (args) => {
  return Promise.resolve()
    .then(() => {
      tools.logInfo('Updating local configuration - custom init');

      const customConfig = innerGlobal.getCustomConfig();

      if (!customConfig) {
        throw new Error('Custom config not found... run the command "npm run init:custom" to generate your customized config');
      }

      let defaultPackages = [];
      defaultPackages = getInputPackages(args.project, args.pkg, args.team, args.prjOnly, args.containerOnly);

      return innerGlobal.updateConfig({
        project: customConfig.project,
        packages: [...defaultPackages, ...customConfig.packages.map((p) => p.name)],
        packagesBranches: customConfig.packages,
        remotes: customConfig.remotes,
        reset: true,
      });
    })
    .catch((e) => {
      throw e;
    });
};

const initConfigCore = (args) => {
  return Promise.resolve()
    .then(() => {
      tools.logInfo('Updating local configuration');

      let packages = [],
        remotes = [];
      if (args.project || args.pkg) {
        packages = getInputPackages(args.project, args.pkg, args.team, args.prjOnly, args.containerOnly);
        tools.logInfo('Found packages : ');
        console.log(packages);
      }

      if (args.remote) {
        const remote = innerRemotes.getCsdrRemotes()[args.remote];
        if (remote) {
          remotes.push(args.remote);
        }
      }

      return innerGlobal.updateConfig({ project: args.project, packages: packages, remotes: remotes, reset: args.reset });
    })
    .catch((e) => {
      throw e;
    });
};

const initConfigProjectsGroup = (projectsGroup, euiVersion) => {
  return Promise.resolve()
    .then(() => {
      tools.logInfo('Updating local configuration');

      const projects = innerProjects.getCsdrProjectsGroupForEuiVersion(projectsGroup, euiVersion);

      return innerGlobal.updateConfig({ projects });
    })
    .catch((e) => {
      throw e;
    });
};

const getInputPackages = (project, pkg, team, prjOnly, containerOnly) => {
  tools.logInfo('Gathering team packages');

  let packages = [];

  // when package is provided, we initialize this package only
  if (pkg) {
    tools.logTitle(`Creating package entry for : ${pkg}`);
    addPackage(pkg);

  // when project or project and team are provided
  } else {
    if (!containerOnly && !prjOnly) {
      tools.logTitle(`Creating packages entries for project:${project}`);

      const prj = innerProjects.getCsdrProject(project);

      if (!prj) {
        throw new Error(`The provided project : ${project} DOES NOT EXIST in CSDR config`);
      }

      if (prj.packages) {
        prj.packages.forEach(addPackage);
      }
    }
  }

  if (Object.keys(packages).length === 0 && !containerOnly) {
    tools.logWarning('WARNING: No packages declared for project.');
  }

  return packages;

  function addPackage(p) {
    if (!innerPackages.getCsdrPackages()[p]) {
      tools.logWarning(`WARNING: package "${p}" is not a valid package`);
      return;
    }

    const csdrPackage = innerPackages.getCsdrPackages()[p];
    if (
      typeof team === 'undefined' ||
      team === 'all' ||
      (csdrPackage.teams && (csdrPackage.teams.indexOf(team) >= 0 || csdrPackage.teams.indexOf('all') >= 0))
    ) {
      packages.push(p);
    }
  }
};
