'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.componentToPrintableForDiff = componentToPrintableForDiff;
exports.prettifyFieldName = prettifyFieldName;
exports.getDiffBetweenObjects = getDiffBetweenObjects;
exports.diffBetweenComponentsObjects = diffBetweenComponentsObjects;

var _ramda;

function _load_ramda() {
  return _ramda = _interopRequireDefault(require('ramda'));
}

var _chalk;

function _load_chalk() {
  return _chalk = _interopRequireDefault(require('chalk'));
}

var _objectDiff;

function _load_objectDiff() {
  return _objectDiff = _interopRequireDefault(require('object-diff'));
}

var _normalizePath;

function _load_normalizePath() {
  return _normalizePath = _interopRequireDefault(require('normalize-path'));
}

var _arrayDifference;

function _load_arrayDifference() {
  return _arrayDifference = _interopRequireDefault(require('array-difference'));
}

var _consumerComponent;

function _load_consumerComponent() {
  return _consumerComponent = _interopRequireDefault(require('../component/consumer-component'));
}

var _constants;

function _load_constants() {
  return _constants = require('../../constants');
}

var _;

function _load_() {
  return _ = require('..');
}

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function componentToPrintableForDiff(component) {
  var obj = {};
  var parsePackages = function parsePackages(packages) {
    return !(_ramda || _load_ramda()).default.isEmpty(packages) && !(_ramda || _load_ramda()).default.isNil(packages) ? Object.keys(packages).map(function (key) {
      return `${key}@${packages[key]}`;
    }) : null;
  };
  var lang = component.lang,
      compiler = component.compiler,
      tester = component.tester,
      dependencies = component.dependencies,
      devDependencies = component.devDependencies,
      packageDependencies = component.packageDependencies,
      devPackageDependencies = component.devPackageDependencies,
      peerPackageDependencies = component.peerPackageDependencies,
      envsPackageDependencies = component.envsPackageDependencies,
      files = component.files,
      mainFile = component.mainFile,
      deprecated = component.deprecated;

  var parsedDevPackageDependencies = parsePackages(devPackageDependencies) || [];
  var parsedEnvsPackageDependencies = parsePackages(envsPackageDependencies) || [];
  var printableDevPackageDependencies = parsedDevPackageDependencies.concat(parsedEnvsPackageDependencies);

  obj.id = component.id.toStringWithoutScope();
  obj.compiler = compiler ? compiler.name : null;
  obj.language = lang || null;
  obj.tester = tester ? tester.name : null;
  obj.mainFile = mainFile ? (0, (_normalizePath || _load_normalizePath()).default)(mainFile) : null;
  obj.dependencies = dependencies.toStringOfIds().concat(parsePackages(packageDependencies)).filter(function (x) {
    return x;
  });
  obj.devDependencies = devDependencies.toStringOfIds().concat(printableDevPackageDependencies).filter(function (x) {
    return x;
  });
  obj.peerDependencies = parsePackages(peerPackageDependencies);

  obj.files = files && !(_ramda || _load_ramda()).default.isEmpty(files) && !(_ramda || _load_ramda()).default.isNil(files) ? files.filter(function (file) {
    return !file.test;
  }).map(function (file) {
    return (0, (_normalizePath || _load_normalizePath()).default)(file.relative);
  }) : null;
  obj.specs = files && !(_ramda || _load_ramda()).default.isEmpty(files) && !(_ramda || _load_ramda()).default.isNil(files) && (_ramda || _load_ramda()).default.find((_ramda || _load_ramda()).default.propEq('test', true))(files) ? files.filter(function (file) {
    return file.test;
  }).map(function (file) {
    return (0, (_normalizePath || _load_normalizePath()).default)(file.relative);
  }) : null;
  obj.deprecated = deprecated ? 'True' : null;
  return obj;
}

function prettifyFieldName(field) {
  return `${field[0].toUpperCase()}${field.substr(1)}`.replace(/([A-Z])/g, ' $1').trim();
}

function comparator(a, b) {
  if (a instanceof Array && b instanceof Array) {
    return (_ramda || _load_ramda()).default.isEmpty((0, (_arrayDifference || _load_arrayDifference()).default)(a, b));
  }
  return a === b;
}

function getDiffBetweenObjects(objectLeft, objectRight) {
  return (_objectDiff || _load_objectDiff()).default.custom({
    equal: comparator
  }, objectLeft, objectRight);
}

function diffBetweenComponentsObjects(consumer, componentLeft, componentRight) {
  var componentMap = consumer.bitMap.getComponent(componentLeft.id, false, true, true);
  if (componentMap && componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.IMPORTED) {
    componentLeft.stripOriginallySharedDir(consumer.bitMap);
    componentRight.stripOriginallySharedDir(consumer.bitMap);
  }
  var printableLeft = componentToPrintableForDiff(componentLeft);
  var printableRight = componentToPrintableForDiff(componentRight);
  var fieldsDiff = getDiffBetweenObjects(printableLeft, printableRight);
  if (!componentLeft.version || !componentRight.version) {
    throw new Error('diffBetweenComponentsObjects component does not have a version');
  }
  var areVersionsTheSame = componentLeft.version === componentRight.version;
  var labelLeft = areVersionsTheSame ? `${componentLeft.version} original` : componentLeft.version;
  var labelRight = areVersionsTheSame ? `${componentRight.version} modified` : componentRight.version;
  var titleLeft = function titleLeft(field) {
    return `--- ${prettifyFieldName(field)} (${labelLeft})\n`;
  };
  var titleRight = function titleRight(field) {
    return `+++ ${prettifyFieldName(field)} (${labelRight})\n`;
  };
  var printFieldValue = function printFieldValue(fieldValue) {
    if (typeof fieldValue === 'string') return fieldValue;
    if (Array.isArray(fieldValue)) return `[ ${fieldValue.join(', ')} ]`;
    throw new Error(`diffBetweenComponentsObjects: not support ${typeof fieldValue}`);
  };
  var printFieldLeft = function printFieldLeft(field) {
    var fieldValue = printableLeft[field];
    if (!fieldValue) return '';
    return `- ${printFieldValue(fieldValue)}\n`;
  };
  var printFieldRight = function printFieldRight(field) {
    var fieldValue = printableRight[field];
    if (!fieldValue) return '';
    return `+ ${printFieldValue(fieldValue)}\n`;
  };
  var fieldsDiffOutput = Object.keys(fieldsDiff).map(function (field) {
    var title = titleLeft(field) + (_chalk || _load_chalk()).default.bold(titleRight(field));
    var value = (_chalk || _load_chalk()).default.red(printFieldLeft(field)) + (_chalk || _load_chalk()).default.green(printFieldRight(field));
    var diffOutput = title + value;
    return { fieldName: field, diffOutput };
  });

  var dependenciesOutput = function dependenciesOutput() {
    var dependenciesLeft = componentLeft.getAllDependencies();
    var dependenciesRight = componentRight.getAllDependencies();
    if ((_ramda || _load_ramda()).default.isEmpty(dependenciesLeft) || (_ramda || _load_ramda()).default.isEmpty(dependenciesRight)) return [];
    return dependenciesLeft.reduce(function (acc, dependencyLeft) {
      var idStr = dependencyLeft.id.toString();
      var dependencyRight = dependenciesRight.find(function (dep) {
        return dep.id.toString() === idStr;
      });
      if (!dependencyRight) return acc;
      if (JSON.stringify(dependencyLeft.relativePaths) === JSON.stringify(dependencyRight.relativePaths)) return acc;
      var fieldName = `Dependency ${idStr} relative-paths`;
      var title = titleLeft(fieldName) + (_chalk || _load_chalk()).default.bold(titleRight(fieldName));
      var getValue = function getValue(fieldValue, left) {
        if ((_ramda || _load_ramda()).default.isEmpty(fieldValue)) return '';
        var sign = left ? '-' : '+';
        var jsonOutput = JSON.stringify(fieldValue, null, `${sign} `);
        return `${jsonOutput}\n`;
      };
      var value = (_chalk || _load_chalk()).default.red(getValue(dependencyLeft.relativePaths, true)) + (_chalk || _load_chalk()).default.green(getValue(dependencyRight.relativePaths, false));
      var diffOutput = title + value;
      acc.push({ fieldName, diffOutput });
      return acc;
    }, []);
  };

  var envs = ['compiler', 'tester'];
  var fieldsEnvsConfigOutput = envs.map(function (env) {
    // $FlowFixMe
    var leftConfig = componentLeft[env] && componentLeft[env].dynamicConfig ? componentLeft[env].dynamicConfig : {};
    var rightConfig = // $FlowFixMe
    componentRight[env] && componentRight[env].dynamicConfig ? componentRight[env].dynamicConfig : {};
    // $FlowFixMe we remove the null later
    if (JSON.stringify(leftConfig) === JSON.stringify(rightConfig)) return null;
    var fieldName = `${env} configuration`;
    var title = titleLeft(fieldName) + (_chalk || _load_chalk()).default.bold(titleRight(fieldName));
    var getValue = function getValue(fieldValue, left) {
      if ((_ramda || _load_ramda()).default.isEmpty(fieldValue)) return '';
      var sign = left ? '-' : '+';
      var jsonOutput = JSON.stringify(fieldValue, null, `${sign} `);
      return `${jsonOutput}\n`;
    };
    var value = (_chalk || _load_chalk()).default.red(getValue(leftConfig, true)) + (_chalk || _load_chalk()).default.green(getValue(rightConfig, false));

    var diffOutput = title + value;
    return { fieldName, diffOutput };
  }).filter(function (x) {
    return x;
  });

  var allDiffs = [].concat(_toConsumableArray(fieldsDiffOutput), _toConsumableArray(fieldsEnvsConfigOutput), _toConsumableArray(dependenciesOutput()));
  return (_ramda || _load_ramda()).default.isEmpty(allDiffs) ? undefined : allDiffs;
}