'use strict';

var _path = _interopRequireDefault(require('path'));

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

var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol;
var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol;
var Promise = global[Symbol.for('jest-native-promise')] || global.Promise;

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  try {
    var info = gen[key](arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }
  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}

function _asyncToGenerator(fn) {
  return function() {
    var self = this,
      args = arguments;
    return new Promise(function(resolve, reject) {
      var gen = fn.apply(self, args);
      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value);
      }
      function _throw(err) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err);
      }
      _next(undefined);
    });
  };
}

const FRAMEWORK_INITIALIZER = require.resolve('./jestAdapterInit');

const jestAdapter =
  /*#__PURE__*/
  (function() {
    var _ref = _asyncToGenerator(function*(
      globalConfig,
      config,
      environment,
      runtime,
      testPath
    ) {
      const _runtime$requireInter = runtime.requireInternalModule(
          FRAMEWORK_INITIALIZER
        ),
        initialize = _runtime$requireInter.initialize,
        runAndTransformResultsToJestFormat =
          _runtime$requireInter.runAndTransformResultsToJestFormat;

      runtime
        .requireInternalModule(
          _path.default.resolve(__dirname, './jestExpect.js')
        )
        .default({
          expand: globalConfig.expand
        });

      const getPrettier = () =>
        config.prettierPath ? require(config.prettierPath) : null;

      const getBabelTraverse = () => require('@babel/traverse').default;

      const _initialize = initialize({
          config,
          environment,
          getBabelTraverse,
          getPrettier,
          globalConfig,
          localRequire: runtime.requireModule.bind(runtime),
          parentProcess: process,
          testPath
        }),
        globals = _initialize.globals,
        snapshotState = _initialize.snapshotState;

      if (config.timers === 'fake') {
        // during setup, this cannot be null (and it's fine to explode if it is)
        environment.fakeTimers.useFakeTimers();
      }

      globals.beforeEach(() => {
        if (config.resetModules) {
          runtime.resetModules();
        }

        if (config.clearMocks) {
          runtime.clearAllMocks();
        }

        if (config.resetMocks) {
          runtime.resetAllMocks();

          if (config.timers === 'fake') {
            // during setup, this cannot be null (and it's fine to explode if it is)
            environment.fakeTimers.useFakeTimers();
          }
        }

        if (config.restoreMocks) {
          runtime.restoreAllMocks();
        }
      });
      config.setupFilesAfterEnv.forEach(path => runtime.requireModule(path));
      runtime.requireModule(testPath);
      const results = yield runAndTransformResultsToJestFormat({
        config,
        globalConfig,
        testPath
      });
      return _addSnapshotData(results, snapshotState);
    });

    return function jestAdapter(_x, _x2, _x3, _x4, _x5) {
      return _ref.apply(this, arguments);
    };
  })();

const _addSnapshotData = (results, snapshotState) => {
  results.testResults.forEach(({fullName, status}) => {
    if (status === 'pending' || status === 'failed') {
      // if test is skipped or failed, we don't want to mark
      // its snapshots as obsolete.
      snapshotState.markSnapshotsAsCheckedForTest(fullName);
    }
  });
  const uncheckedCount = snapshotState.getUncheckedCount();
  const uncheckedKeys = snapshotState.getUncheckedKeys();

  if (uncheckedCount) {
    snapshotState.removeUncheckedKeys();
  }

  const status = snapshotState.save();
  results.snapshot.fileDeleted = status.deleted;
  results.snapshot.added = snapshotState.added;
  results.snapshot.matched = snapshotState.matched;
  results.snapshot.unmatched = snapshotState.unmatched;
  results.snapshot.updated = snapshotState.updated;
  results.snapshot.unchecked = !status.deleted ? uncheckedCount : 0; // Copy the array to prevent memory leaks

  results.snapshot.uncheckedKeys = Array.from(uncheckedKeys);
  return results;
};

module.exports = jestAdapter;
