'use strict';

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

var _regenerator;

function _load_regenerator() {
  return _regenerator = _interopRequireDefault(require('babel-runtime/regenerator'));
}

var _ramda;

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

var _bitMap;

function _load_bitMap() {
  return _bitMap = _interopRequireDefault(require('../bit-map'));
}

var _constants;

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

var _migrationHelper;

function _load_migrationHelper() {
  return _migrationHelper = _interopRequireDefault(require('../../migration/migration-helper'));
}

var _migrationHelper2;

function _load_migrationHelper2() {
  return _migrationHelper2 = require('../../migration/migration-helper');
}

var _logger;

function _load_logger() {
  return _logger = _interopRequireDefault(require('../../logger/logger'));
}

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

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

var globalVerbose = false;

/**
 * Running migration process for consumer 
 * (Currently support only bitmap migration, but might contain other stores in the future)
 * @param {string} bitmapVersion - The current bitmap version
 * @param {Object} migratonManifest - A manifest which define what migrations to run
 * @param {BitMap} bitMap - bit map object
 * @param {boolean} verbose - print logs
 */

exports.default = function () {
  var _ref = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee(bitmapVersion, migratonManifest, bitMap) {
    var verbose = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
    var bitMapMigrations, newBitMap, result;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            globalVerbose = verbose;

            bitMapMigrations = (0, (_migrationHelper || _load_migrationHelper()).default)((_constants || _load_constants()).BIT_VERSION, bitmapVersion, migratonManifest, verbose);
            newBitMap = _runAllMigrationsForStore('bitmap', bitMap, bitMapMigrations);
            // Run more migration for other stores (like bit.json)

            result = { bitMap: newBitMap };
            return _context.abrupt('return', result);

          case 5:
          case 'end':
            return _context.stop();
        }
      }
    }, _callee, this);
  }));

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

  return migrate;
}();

/**
 * Runs all the migrations for all the versions for store (bit map) file
 * @param {string} storeType - type of store (bitmap / bitjson etc)
 * @param {string} store - store data
 * @param {VersionMigrations[]} migrations
 */


var _runAllMigrationsForStore = function _runAllMigrationsForStore(storeType, store, migrations) {
  // Make sure we got a store
  if (!store) {
    return null;
  }
  (_logger || _load_logger()).default.debug(`start updating store ${storeType}`);
  (_ramda || _load_ramda()).default.forEach(_runAllVersionMigrationsForStore(storeType, store), migrations);
  return store;
};

/**
 * Runs all the the migration in specific version on store
 * @param {string} storeType - type of store (bitmap / bitjson etc)
 * @param {string} store - store data
 */
var _runAllVersionMigrationsForStore = function _runAllVersionMigrationsForStore(storeType, store) {
  return function (migrations) {
    var versionNumber = Object.keys(migrations)[0];
    (_logger || _load_logger()).default.debug(`updating store ${storeType} to version ${versionNumber}`);
    var migrationForStoreType = migrations[versionNumber][storeType];
    // There is no migration for this type of object for this version
    if (!migrationForStoreType) return store;
    (_ramda || _load_ramda()).default.forEach(_runOneMigrationForStore(storeType, store), migrationForStoreType);
    return store;
  };
};

/**
 * Run specific migration function on a store
 * @param {string} storeType - type of store (bitmap / bitjson etc)
 * @param {string} store - store data
 */
var _runOneMigrationForStore = function _runOneMigrationForStore(storeType, store) {
  return function (migration) {
    (_logger || _load_logger()).default.debug(`running migration: ${migration.name} on ${storeType}`);
    if (globalVerbose) console.log(`running migration: ${migration.name} on ${storeType}`);
    try {
      var migratedStore = migration.migrate(store);
      return migratedStore;
    } catch (err) {
      (_logger || _load_logger()).default.error(`FAILED - running migration: ${migration.name} on ${storeType}`);
      throw err;
    }
  };
};