"use strict";

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

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = paintComponent;

function _chalk() {
  const data = _interopRequireDefault(require("chalk"));

  _chalk = function () {
    return data;
  };

  return data;
}

function _table() {
  const data = require("table");

  _table = function () {
    return data;
  };

  return data;
}

function _padRight() {
  const data = _interopRequireDefault(require("pad-right"));

  _padRight = function () {
    return data;
  };

  return data;
}

function _consumerComponent() {
  const data = _interopRequireDefault(require("../../consumer/component/consumer-component"));

  _consumerComponent = function () {
    return data;
  };

  return data;
}

function _docsTemplate() {
  const data = _interopRequireDefault(require("./docs-template"));

  _docsTemplate = function () {
    return data;
  };

  return data;
}

function _componentsObjectDiff() {
  const data = require("../../consumer/component-ops/components-object-diff");

  _componentsObjectDiff = function () {
    return data;
  };

  return data;
}

const COLUMN_WIDTH = 50;
const tableColumnConfig = {
  columns: {
    // $FlowFixMe
    1: {
      alignment: 'left',
      width: COLUMN_WIDTH
    },
    // $FlowFixMe
    2: {
      alignment: 'left',
      width: COLUMN_WIDTH
    }
  }
};

function paintComponent(component, componentModel, showRemoteVersion, detailed, dependenciesInfo, dependentsInfo) {
  return componentModel ? paintWithCompare() : paintWithoutCompare();

  function paintWithoutCompare() {
    const printableComponent = (0, _componentsObjectDiff().componentToPrintableForDiff)(component);
    const rows = getFields().map(field => {
      const arr = [];
      const title = (0, _componentsObjectDiff().prettifyFieldName)(field);
      if (!printableComponent[field]) return null;
      arr.push(_chalk().default.cyan(title));
      if (!printableComponent[field]) return null;

      if (printableComponent[field]) {
        if (printableComponent[field] instanceof Array) {
          arr.push(printableComponent[field].map(str => calculatePadRightLength(str, COLUMN_WIDTH)).join(' ').trim());
        } else arr.push(printableComponent[field]);
      }

      return arr;
    }).filter(x => x);
    const componentTable = (0, _table().table)(rows, tableColumnConfig);
    const dependenciesTableStr = showRemoteVersion ? generateDependenciesTable() : '';
    const dependentsInfoTableStr = generateDependentsInfoTable();
    const dependenciesInfoTableStr = generateDependenciesInfoTable();
    return componentTable + dependenciesTableStr + dependentsInfoTableStr + dependenciesInfoTableStr + (0, _docsTemplate().default)(component.docs);
  }

  function paintWithCompare() {
    if (!componentModel) throw new Error('paintWithCompare, componentModel must be defined');
    const printableOriginalComponent = (0, _componentsObjectDiff().componentToPrintableForDiff)(component);
    printableOriginalComponent.id += ' [file system]';
    const printableComponentToCompare = (0, _componentsObjectDiff().componentToPrintableForDiff)(componentModel);
    const componentsDiffs = (0, _componentsObjectDiff().getDiffBetweenObjects)(printableOriginalComponent, printableComponentToCompare);
    const rows = getFields().map(field => {
      const arr = [];
      if (!printableOriginalComponent[field] && !printableComponentToCompare[field]) return null;
      const title = `${field[0].toUpperCase()}${field.substr(1)}`.replace(/([A-Z])/g, ' $1').trim();
      arr.push(field in componentsDiffs && field !== 'id' ? _chalk().default.red(title) : _chalk().default.cyan(title));

      if (printableComponentToCompare[field] instanceof Array) {
        arr.push(printableComponentToCompare[field].map(str => calculatePadRightLength(str, COLUMN_WIDTH)).join(' ').trim());
      } else {
        arr.push(printableComponentToCompare[field]);
      }

      if (printableOriginalComponent[field] instanceof Array) {
        arr.push(printableOriginalComponent[field].map(str => calculatePadRightLength(str, COLUMN_WIDTH)).join(' ').trim());
      } else {
        arr.push(printableOriginalComponent[field]);
      }

      return arr;
    }).filter(x => x);
    const componentTable = (0, _table().table)(rows, tableColumnConfig);
    const dependenciesTableStr = generateDependenciesTable();
    return componentTable + dependenciesTableStr;
  }

  function getFields() {
    const fields = ['id', 'compiler', 'tester', 'language', 'mainFile', 'dependencies', 'devDependencies', 'compilerDependencies', 'testerDependencies', 'packages', 'devPackages', 'peerDependencies', 'files', 'specs', 'deprecated'];

    if (detailed) {
      const extraFields = ['overridesDependencies', 'overridesDevDependencies', 'overridesPeerDependencies'];
      fields.push(...extraFields);
    }

    return fields;
  }

  function generateDependenciesTable() {
    if (!component.hasDependencies()) {
      return '';
    }

    const dependencyHeader = [];

    if (showRemoteVersion) {
      dependencyHeader.push(['Dependency ID', 'Current Version', 'Local Version', 'Remote Version']);
    } else {
      dependencyHeader.push(['Dependencies']);
    }

    const getDependenciesRows = (dependencies, title) => {
      const dependencyRows = [];
      dependencies.forEach(dependency => {
        let dependencyId = showRemoteVersion ? dependency.id.toStringWithoutVersion() : dependency.id.toString();
        dependencyId = title ? `${dependencyId} (${title})` : dependencyId;
        const row = [dependencyId];

        if (showRemoteVersion) {
          const dependencyVersion = dependency.currentVersion;
          const localVersion = dependency.localVersion;
          const remoteVersion = dependency.remoteVersion ? dependency.remoteVersion : null; // if all versions are equal, paint them with green. Otherwise, paint with red

          const color = remoteVersion && remoteVersion === localVersion && remoteVersion === dependencyVersion || !remoteVersion && localVersion === dependencyVersion ? 'green' : 'red'; // $FlowFixMe

          row.push(_chalk().default[color](dependencyVersion)); // $FlowFixMe

          row.push(_chalk().default[color](localVersion)); // $FlowFixMe

          row.push(remoteVersion ? _chalk().default[color](remoteVersion) : 'N/A');
        }

        dependencyRows.push(row);
      });
      return dependencyRows;
    };

    const dependenciesRows = getDependenciesRows(component.dependencies.get());
    const devDependenciesRows = getDependenciesRows(component.devDependencies.get(), 'dev');
    const compilerDependenciesRows = getDependenciesRows(component.compilerDependencies.get(), 'compiler');
    const testerDependenciesRows = getDependenciesRows(component.testerDependencies.get(), 'tester');
    const allDependenciesRows = [...dependenciesRows, ...devDependenciesRows, ...compilerDependenciesRows, ...testerDependenciesRows];
    const dependenciesTable = (0, _table().table)(dependencyHeader.concat(allDependenciesRows));
    return dependenciesTable;
  }

  function generateDependentsInfoTable() {
    if (!dependentsInfo.length) {
      return '';
    }

    const dependentsHeader = [];
    dependentsHeader.push([_chalk().default.cyan('Dependent ID'), _chalk().default.cyan('Depth'), _chalk().default.cyan('Immediate Dependency'), _chalk().default.cyan('Dependent type')]);
    const allDependenciesRows = dependentsInfo.map(dependent => {
      const row = [];
      row.push(dependent.id);
      row.push(dependent.depth);
      row.push(dependent.parent);
      row.push(dependent.dependencyType);
      return row;
    });
    const dependentsTable = (0, _table().table)(dependentsHeader.concat(allDependenciesRows));
    return `\n${_chalk().default.bold('Dependents Details')}\n${dependentsTable}`;
  }

  function generateDependenciesInfoTable() {
    if (!dependenciesInfo.length) {
      return '';
    }

    const dependenciesHeader = [];
    dependenciesHeader.push([_chalk().default.cyan('Dependency ID'), _chalk().default.cyan('Depth'), _chalk().default.cyan('Immediate Dependent'), _chalk().default.cyan('Dependency type')]);
    const allDependenciesRows = dependenciesInfo.map(dependency => {
      const row = [];
      row.push(dependency.id);
      row.push(dependency.depth);
      row.push(dependency.parent);
      row.push(dependency.dependencyType);
      return row;
    });
    const dependenciesTable = (0, _table().table)(dependenciesHeader.concat(allDependenciesRows));
    return `\n${_chalk().default.bold('Dependencies Details')}\n${dependenciesTable}`;
  }

  function calculatePadRightLength(str, columnWidth) {
    if (!str) return '';
    const padRightCount = Math.ceil(str.length / columnWidth) * columnWidth;
    return str.length > columnWidth ? (0, _padRight().default)(str, padRightCount, ' ') : (0, _padRight().default)(str, columnWidth, ' ');
  }
}