'use strict';

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

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

// INNER
const innerGlobal = require('./global');
const innerPackages = require('./packages');


module.exports.getRemote = (remoteName = null, standalone = false) => {
  // if not provided as param, we fetch them from the command line (local operations)
  if (!remoteName) {
    remoteName = tools.getArgs().root;
  }

  let configOptions;

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

  let remotesConfig;
  let remotePath;
  if (tools.isDirExists(path.join(process.cwd(), '.config'))) {
    remotesConfig = require(path.join(process.cwd(), '.config', 'remotes', '.euirc-remotes.json'));
    remotePath = path.join(configOptions.CSDR_REMOTES_CONFIG_PATH , remoteName);
  } else {
    remotesConfig = require(path.join(process.cwd(), '.csdr', '.euirc-csdr-remotes.json'));
    remotePath = path.join(configOptions.CSDR_REMOTES_CONFIG_PATH , 'assets', remoteName);
  }

  const remoteConfig = remotesConfig[remoteName];

  if (!tools.isDirExists(remotePath)) {
    throw new Error(`Remote ${remoteName} cannot be found in the remotes global config - check ${configOptions.CSDR_REMOTES_CONFIG_PATH} for available remotes`);
  }

  const remoteRootPath = path.join(process.cwd(), 'remotes', remoteName);

  let csdrFlag, standaloneFlag;
  if (standalone) {
    csdrFlag = false;
    standaloneFlag = true;
  } else {
    csdrFlag = true;
    standaloneFlag = false;
  }

  const remote = {
    csdr: csdrFlag,
    standalone: standaloneFlag,
    name: remoteName,
    element: true,
    remote: true,
    virtual: true,
    paths: {
      root: remoteRootPath,
      src: path.join(remoteRootPath, 'src'),
      dist: path.join(remoteRootPath, 'dist'),
      publish: path.join(remoteRootPath, 'dist'), // maintain compat with core publish utils
      fromRoot: `remotes/${remoteName}`,
      repoNodeModules: path.join(remoteRootPath, 'node_modules'),
    },
    angularConfig: tools.getJsonFileContent(path.join(remotePath, 'angular-config.json')),
    dependencies: tools.getJsonFileContent(path.join(remotePath, 'dependencies.json')),
    devopsMetadataFile: `${remoteName}-build-metadata.json`,
    devopsVersionsMetadataFile: `${remoteName}-versions-metadata.json`,
    devopsHistoryMetadataFile: `${remoteName}-history-metadata-v2.json`,
    devopsEnvsMetadataFile: `${remoteName}-envs-metadata.json`,
    ...remoteConfig,
  }

  // check notification method
  if (remote.notification) {
    if (remote.notification.client === 'MSTEAMS') {
      remote.msteamsActive = true;
    } else {
      remote.msteamsActive = false;
    }
  }

  if (!remote.dependencies.composite) {
    throw new Error('The remote config does not contains the manadatory "composite" dependencies');
  }

  return remote;
}


module.exports.isVirtualRemote = (remoteName) => {
  let remotesConfig;
  console.log(tools.isDirExists())
  if (tools.isDirExists(path.join(process.cwd(), '.config'))) {
    remotesConfig = require(path.join(process.cwd(), '.config', 'remotes', '.euirc-remotes.json'));
  } else {
    remotesConfig = require(path.join(process.cwd(), '.csdr', '.euirc-csdr-remotes.json'));
  }

  const remoteConfig = remotesConfig[remoteName];

  return remoteConfig !== undefined;
}




module.exports.getCsdrRemotes = (hostName, euiVersion) => {

  const hostNameFilterFn = (r) => {
    if (r.build) {
      if (!r.build.appTarget || r.build.appTarget === 'MWP_ONLY') {
        if (hostName === 'my-workplace' || hostName) {
          return true;
        }
      } else if (r.build.appTarget === 'SEDIA_ONLY') {
        if (hostName === 'sedia') {
          return true;
        }
      } else if (r.build.appTarget === 'MWP_SEDIA') {
        if (hostName === 'my-workplace' || hostName === 'sedia') {
          return true;
        }
      } else {
        return false;
      }
    }
  }

  tools.logInfo(`Getting remotes`);

  if (hostName) {
    tools.logInfo(`--- for host: ${hostName}`);
  }
  if (euiVersion) {
    tools.logInfo(`--- for euiVersion: ${euiVersion}`);
  }

  let remotesConfig;
  if (tools.isDirExists(path.join(process.cwd(), '.config'))) {
    remotesConfig = require(path.join(process.cwd(), '.config', 'remotes', '.euirc-remotes.json'));
  } else {
    remotesConfig = require(path.join(process.cwd(), '.csdr', '.euirc-csdr-remotes.json'));
  }

  let remotesArray = Object.keys(remotesConfig).map((r) => {
    const remote = remotesConfig[r];
    remote.name = r;
    return remote;
  });

  if (hostName) {
    remotesArray = remotesArray.filter(r => hostNameFilterFn(r));
  }
  if (euiVersion) {
    remotesArray = remotesArray.filter(r => r.euiVersion === euiVersion);
  }

  const outRemotes = {};
  remotesArray.forEach((r) => {
    outRemotes[r.name] = r;
  })

  return outRemotes;
}

module.exports.getCsdrRemotesArray = (hostName, euiVersion) => {
  const remotes = this.getCsdrRemotes(hostName, euiVersion);

  return Object.keys(remotes).map((r) => {
    return remotes[r];
  })
}


module.exports.getRemotes = () => {
  const remotes = innerGlobal.getConfig().remotes;
  const remotesKeys = Object.keys(remotes);

  let outputRemotes = [];
  remotesKeys.forEach((r) => {
    outputRemotes.push(this.getRemote(r));
  })
  return outputRemotes;
}

module.exports.getRemoteByNpmPkg = (npmPkg, fromCsdrConfig) => {
  let remotes;

  if (fromCsdrConfig) {
    remotes = this.getCsdrRemotesArray();

  } else {
    remotes = this.getRemotes();
  }

  return remotes.filter((r) => {
    return r.npmPkg === npmPkg;
  })[0];
}

module.exports.isLocalRemote = (npmPkg) => {
  return this.getRemoteByNpmPkg(npmPkg) !== undefined;
}

module.exports.getRemotesPackages = (remotes) => {
  let packages = [], deps = {};

  remotes.forEach((r) => {
    const remote = this.getRemote(r);

    // check sub-entry declared rootNpmPkg in config, in that case we take the real root npmPkg
    const rootNpmPkg = remote.skeletonConfig.rootNpmPkg;
    let rootNpmPkgName = rootNpmPkg;
    if (rootNpmPkg.split('/').length > 2) {
      rootNpmPkgName = rootNpmPkg.substr(0, rootNpmPkg.lastIndexOf('/'));
    }

    // adding dependencies except the rootPkg dep (as it's installed as source)
    const npmPkgs = Object.keys(remote.dependencies.composite);
    npmPkgs.forEach((n) => {
      if (n !== rootNpmPkgName) {
        deps[n] = remote.dependencies.composite[n];
      }
    });

    // adding the deps-base if the remote as any
    deps = { ...deps, ...remote.dependencies.base };

    // adding the package root as source
    const pkg = innerPackages.getPackageByNpmPkg(rootNpmPkgName, true);
    packages.push(pkg.name);

    packages = packages.map((p) => {
      return {
        name: p,
        branch: 'develop'
      }
    });
  });

  return {
    deps,
    packages: tools.removeArrayDuplicates(packages)
  }
}
