"use strict";

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

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

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

  _bluebird = function () {
    return data;
  };

  return data;
}

function _serializeError() {
  const data = _interopRequireDefault(require("serialize-error"));

  _serializeError = function () {
    return data;
  };

  return data;
}

function _test() {
  const data = require("../api/consumer/lib/test");

  _test = function () {
    return data;
  };

  return data;
}

function _loader() {
  const data = _interopRequireDefault(require("../cli/loader"));

  _loader = function () {
    return data;
  };

  return data;
}

function _externalErrors() {
  const data = _interopRequireDefault(require("../error/external-errors"));

  _externalErrors = function () {
    return data;
  };

  return data;
}

function _externalError() {
  const data = _interopRequireDefault(require("../error/external-error"));

  _externalError = function () {
    return data;
  };

  return data;
}

// TODO - move to language specific driver.
const testOneComponent = verbose =>
/*#__PURE__*/
function () {
  var _ref = (0, _bluebird().coroutine)(function* (id) {
    // $FlowFixMe
    const res = yield (0, _test().testInProcess)(id, false, verbose);
    return res.results[0];
  });

  return function (_x) {
    return _ref.apply(this, arguments);
  };
}();

function run() {
  const ids = process.env.__ids__ ? process.env.__ids__.split() : undefined;
  const verbose = process.env.__verbose__ === true || process.env.__verbose__ === 'true';
  const includeUnmodified = process.env.__includeUnmodified__ === true || process.env.__includeUnmodified__ === 'true';

  if (!ids || !ids.length) {
    return (0, _test().testInProcess)(undefined, includeUnmodified, verbose).then(results => {
      const serializedResults = serializeResults(results.results); // $FlowFixMe

      process.send(serializedResults); // Make sure the child process will not hang

      process.exit();
    }).catch(e => {
      _loader().default.off();

      const serializedResults = serializeResults(e); // $FlowFixMe

      process.send(serializedResults); // Make sure the child process will not hang

      process.exit();
    });
  }

  const testAllP = ids.map(testOneComponent(verbose));
  return Promise.all(testAllP).then(results => {
    const serializedResults = serializeResults(results); // $FlowFixMe

    process.send(serializedResults); // Make sure the child process will not hang

    process.exit();
  }).catch(e => {
    _loader().default.off();

    const serializedResults = serializeResults(e); // $FlowFixMe

    process.send(serializedResults); // Make sure the child process will not hang

    process.exit();
  });
}

run();

function serializeResults(results) {
  // if (!results) return undefined;
  if (!results) {
    return {
      type: 'results',
      results: []
    };
  }

  if (results instanceof Error) {
    // In case of external error also serialize the original error
    if (results instanceof _externalErrors().default) {
      results.originalErrors = results.originalErrors.map(_serializeError().default);
    }

    if (results instanceof _externalError().default) {
      results.originalError = (0, _serializeError().default)(results);
    }

    const serializedErr = (0, _serializeError().default)(results);
    const finalResults = {
      type: 'error',
      error: serializedErr
    };
    return finalResults;
  }

  const serializeFailure = failure => {
    if (!failure) return undefined;
    const serializedFailure = failure;

    if (failure.err && failure.err instanceof Error) {
      serializedFailure.err = (0, _serializeError().default)(failure.err);
    }

    return serializedFailure;
  };

  const serializeSpec = spec => {
    if (!spec.failures) return spec;
    spec.failures = spec.failures.map(serializeFailure);
    return spec;
  };

  const serializeResult = result => {
    const specs = result.specs;
    if (!specs || !Array.isArray(specs)) return result;
    result.specs = specs.map(serializeSpec);
    return result;
  };

  const serializedResults = results.map(serializeResult); // $FlowFixMe

  return {
    type: 'results',
    results: serializedResults
  };
}