"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getEjectConfDataToPersist = getEjectConfDataToPersist;
exports.writeEnvFiles = writeEnvFiles;
exports.populateEnvFilesToWrite = populateEnvFilesToWrite;
exports.default = void 0;

function _bluebird() {
  const data = require("bluebird");

  _bluebird = function () {
    return data;
  };

  return data;
}

function _path() {
  const data = _interopRequireDefault(require("path"));

  _path = function () {
    return data;
  };

  return data;
}

function _ramda() {
  const data = _interopRequireDefault(require("ramda"));

  _ramda = function () {
    return data;
  };

  return data;
}

function _config() {
  const data = _interopRequireDefault(require("../config"));

  _config = function () {
    return data;
  };

  return data;
}

function _utils() {
  const data = require("../../utils");

  _utils = function () {
    return data;
  };

  return data;
}

function _generalError() {
  const data = _interopRequireDefault(require("../../error/general-error"));

  _generalError = function () {
    return data;
  };

  return data;
}

function _ejectNoDir() {
  const data = _interopRequireDefault(require("./exceptions/eject-no-dir"));

  _ejectNoDir = function () {
    return data;
  };

  return data;
}

function _configDir() {
  const data = _interopRequireDefault(require("../bit-map/config-dir"));

  _configDir = function () {
    return data;
  };

  return data;
}

function _linkGenerator() {
  const data = require("../../links/link-generator");

  _linkGenerator = function () {
    return data;
  };

  return data;
}

function _compilerExtension() {
  const data = _interopRequireDefault(require("../../extensions/compiler-extension"));

  _compilerExtension = function () {
    return data;
  };

  return data;
}

function _testerExtension() {
  const data = _interopRequireDefault(require("../../extensions/tester-extension"));

  _testerExtension = function () {
    return data;
  };

  return data;
}

function _dataToPersist() {
  const data = _interopRequireDefault(require("../component/sources/data-to-persist"));

  _dataToPersist = function () {
    return data;
  };

  return data;
}

function _constants() {
  const data = require("../../constants");

  _constants = function () {
    return data;
  };

  return data;
}

function _removePath() {
  const data = _interopRequireDefault(require("../component/sources/remove-path"));

  _removePath = function () {
    return data;
  };

  return data;
}

function _abstractConfig() {
  const data = _interopRequireDefault(require("../config/abstract-config"));

  _abstractConfig = function () {
    return data;
  };

  return data;
}

var _default =
/*#__PURE__*/
function () {
  var _ejectConf = (0, _bluebird().coroutine)(function* (component, consumer, configDir) {
    // $FlowFixMe
    const {
      id,
      ejectedPath,
      ejectedFullPath,
      dataToPersist
    } = yield getEjectConfDataToPersist(component, consumer, consumer.bitMap, configDir);
    dataToPersist.addBasePath(consumer.getPath());
    yield dataToPersist.persistAllToFS();
    return {
      id,
      ejectedPath,
      ejectedFullPath
    };
  });

  function ejectConf(_x, _x2, _x3) {
    return _ejectConf.apply(this, arguments);
  }

  return ejectConf;
}();

exports.default = _default;

function getEjectConfDataToPersist(_x4, _x5, _x6, _x7) {
  return _getEjectConfDataToPersist.apply(this, arguments);
}

function _getEjectConfDataToPersist() {
  _getEjectConfDataToPersist = (0, _bluebird().coroutine)(function* (component, consumer, bitMap, configDir) {
    const oldConfigDir = _ramda().default.path(['componentMap', 'configDir'], component);

    const componentMap = component.componentMap;

    if (!componentMap) {
      throw new (_generalError().default)('could not find component in the .bitmap file');
    }

    const componentDir = componentMap.getComponentDir();

    if (!componentDir && configDir.isUnderComponentDir) {
      throw new (_ejectNoDir().default)(component.id.toStringWithoutVersion());
    } // In case the user pass a path with the component dir replace it by the {COMPONENT_DIR} DSL
    // (To better support bit move for example)


    if (componentDir) {
      configDir.replaceByComponentDirDSL(componentDir);
    }

    if (!configDir.isUnderComponentDir) {
      const configDirToValidate = _getDirToValidateAgainstOtherComps(configDir);

      bitMap.validateConfigDir(component.id.toStringWithoutVersion(), configDirToValidate);
    }

    const deleteOldFiles = !!componentMap.configDir && componentMap.configDir !== configDir.linuxDirPath; // Passing here the ENV_TYPE as well to make sure it's not removed since we need it later

    const resolvedConfigDir = configDir.getResolved({
      componentDir
    });
    const ejectedCompilerDirectoryP = populateEnvFilesToWrite({
      configDir: resolvedConfigDir.dirPath,
      env: component.compiler,
      consumer,
      bitMap,
      component,
      deleteOldFiles,
      verbose: false
    });
    const ejectedTesterDirectoryP = populateEnvFilesToWrite({
      configDir: resolvedConfigDir.dirPath,
      env: component.tester,
      consumer,
      bitMap,
      component,
      deleteOldFiles,
      verbose: false
    });
    const [ejectedCompilerDirectory, ejectedTesterDirectory] = yield Promise.all([ejectedCompilerDirectoryP, ejectedTesterDirectoryP]);
    const dataToPersist = new (_dataToPersist().default)();
    if (component.compiler) dataToPersist.merge(component.compiler.dataToPersist);
    if (component.tester) dataToPersist.merge(component.tester.dataToPersist);
    const id = component.id.toStringWithoutVersion();

    if (!consumer) {
      return {
        id,
        ejectedPath: configDir.linuxDirPath,
        dataToPersist
      };
    }

    const bitJsonDir = resolvedConfigDir.getEnvTypeCleaned();
    const consumerPath = consumer.getPath();

    const bitJsonDirFullPath = _path().default.normalize(_path().default.join(consumerPath, bitJsonDir.dirPath));

    const relativeEjectedCompilerDirectory = _getRelativeDir(bitJsonDirFullPath, consumer.toAbsolutePath(ejectedCompilerDirectory));

    const relativeEjectedTesterDirectory = _getRelativeDir(bitJsonDirFullPath, consumer.toAbsolutePath(ejectedTesterDirectory));

    const removedFromOverrides = consumer.config.overrides.removeExactMatch(component.id);
    if (component.compiler) dataToPersist.merge(component.compiler.dataToPersist);
    if (component.tester) dataToPersist.merge(component.tester.dataToPersist);
    const bitJson = getBitJsonToWrite(component, relativeEjectedCompilerDirectory, relativeEjectedTesterDirectory);
    const jsonFilesToWrite = yield bitJson.prepareToWrite({
      workspaceDir: consumer.getPath(),
      componentDir: bitJsonDir.dirPath
    });
    dataToPersist.addManyFiles(jsonFilesToWrite);

    if (removedFromOverrides) {
      const consumerConfigFiles = yield consumer.config.prepareToWrite({
        workspaceDir: consumerPath
      });
      dataToPersist.addManyFiles(consumerConfigFiles);
    }

    if (deleteOldFiles) {
      if (oldConfigDir) {
        const oldBitJsonDir = oldConfigDir.getResolved({
          componentDir
        }).getEnvTypeCleaned();

        const oldBitJsonDirFullPath = _path().default.join(consumerPath, oldBitJsonDir.dirPath);

        if (bitJsonDirFullPath !== oldBitJsonDirFullPath) {
          const bitJsonToRemove = _abstractConfig().default.composeBitJsonPath(oldBitJsonDir.dirPath);

          dataToPersist.removePath(new (_removePath().default)(bitJsonToRemove, true));
        }
      }
    }

    return {
      id,
      ejectedPath: configDir.linuxDirPath,
      ejectedFullPath: bitJsonDir.linuxDirPath,
      dataToPersist
    };
  });
  return _getEjectConfDataToPersist.apply(this, arguments);
}

function writeEnvFiles(_x8) {
  return _writeEnvFiles.apply(this, arguments);
}
/**
 * populates the env files into env.dataToPersist
 */


function _writeEnvFiles() {
  _writeEnvFiles = (0, _bluebird().coroutine)(function* ({
    configDir,
    env,
    consumer,
    component,
    deleteOldFiles,
    verbose = false
  }) {
    if (!env) {
      return '';
    }

    const ejectedDirectory = yield populateEnvFilesToWrite({
      configDir,
      env,
      consumer,
      // $FlowFixMe todo: fix!
      bitMap: consumer.bitMap,
      component,
      deleteOldFiles,
      verbose
    });

    if (env.dataToPersist) {
      if (consumer) env.dataToPersist.addBasePath(consumer.getPath());
      yield env.dataToPersist.persistAllToFS();
    }

    return ejectedDirectory;
  });
  return _writeEnvFiles.apply(this, arguments);
}

function populateEnvFilesToWrite(_x9) {
  return _populateEnvFilesToWrite.apply(this, arguments);
}

function _populateEnvFilesToWrite() {
  _populateEnvFilesToWrite = (0, _bluebird().coroutine)(function* ({
    configDir,
    env,
    consumer,
    bitMap,
    component,
    deleteOldFiles,
    verbose = false
  }) {
    if (!env) {
      return '';
    }

    const envType = env instanceof _compilerExtension().default ? _constants().COMPILER_ENV_TYPE : _constants().TESTER_ENV_TYPE;
    const ejectedDirectory = env.populateDataToPersist({
      configDir,
      deleteOldFiles,
      consumer,
      envType,
      verbose
    });
    const deps = env instanceof _compilerExtension().default ? component.compilerDependencies : component.testerDependencies; // $FlowFixMe will be fixed with the Capsule feature

    const links = yield (0, _linkGenerator().getLinksByDependencies)(configDir, component, deps, consumer, bitMap);
    env.dataToPersist.addManyFiles(links);
    return ejectedDirectory;
  });
  return _populateEnvFilesToWrite.apply(this, arguments);
}

const getBitJsonToWrite = (component, ejectedCompilerDirectory, ejectedTesterDirectory) => {
  const componentConfig = _config().default.fromComponent(component);

  componentConfig.compiler = component.compiler ? component.compiler.toBitJsonObject(ejectedCompilerDirectory) : {};
  componentConfig.tester = component.tester ? component.tester.toBitJsonObject(ejectedTesterDirectory) : {};
  return componentConfig;
};

const _getRelativeDir = (bitJsonDir, envDir) => {
  let res = envDir;
  const sharedStart = (0, _utils().sharedStartOfArray)([bitJsonDir, envDir]);

  if (sharedStart) {
    res = _path().default.relative(sharedStart, envDir);
  }

  return res;
};
/**
 * get the config dir which needed to be searched in other components to validate there is no conflicts
 * That's means check that the dir is not inside the comp dir
 * and get the dir without the dynamic parts
 * @param {*} configDir
 */


const _getDirToValidateAgainstOtherComps = configDir => {
  // In case it's inside the component dir it can't conflicts with other comps
  if (configDir.isUnderComponentDir) {
    return null;
  }

  return configDir.getCleaned({
    cleanComponentDir: false,
    cleanEnvType: true
  }).linuxDirPath;
};