'use strict';

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

var _regenerator;

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

var _bluebird;

function _load_bluebird() {
  return _bluebird = require('bluebird');
}

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

var getMergeResults = function () {
  var _ref3 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4(consumer, modifiedFiles) {
    var _this = this;

    var tmp, conflictResultsP;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            tmp = new (_tmp || _load_tmp()).default(consumer.scope);
            conflictResultsP = modifiedFiles.map(function () {
              var _ref4 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3(modifiedFile) {
                var currentFilePathP, writeFile, baseFilePathP, otherFilePathP, _ref6, _ref7, otherFilePath, baseFilePath, currentFilePath, mergeFilesParams;

                return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
                  while (1) {
                    switch (_context3.prev = _context3.next) {
                      case 0:
                        currentFilePathP = tmp.save(modifiedFile.currentFile.contents);

                        writeFile = function () {
                          var _ref5 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2(file) {
                            return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
                              while (1) {
                                switch (_context2.prev = _context2.next) {
                                  case 0:
                                    return _context2.abrupt('return', tmp.save(file.contents));

                                  case 1:
                                  case 'end':
                                    return _context2.stop();
                                }
                              }
                            }, _callee2, _this);
                          }));

                          return function writeFile(_x5) {
                            return _ref5.apply(this, arguments);
                          };
                        }();

                        baseFilePathP = tmp.save('');
                        otherFilePathP = writeFile(modifiedFile.otherFile);
                        _context3.next = 6;
                        return Promise.all([otherFilePathP, baseFilePathP, currentFilePathP]);

                      case 6:
                        _ref6 = _context3.sent;
                        _ref7 = _slicedToArray(_ref6, 3);
                        otherFilePath = _ref7[0];
                        baseFilePath = _ref7[1];
                        currentFilePath = _ref7[2];
                        mergeFilesParams = {
                          filePath: modifiedFile.filePath,
                          currentFile: {
                            label: modifiedFile.currentFile.version,
                            path: currentFilePath
                          },
                          baseFile: {
                            path: baseFilePath
                          },
                          otherFile: {
                            // $FlowFixMe
                            label: modifiedFile.otherFile.version,
                            path: otherFilePath
                          }
                        };
                        return _context3.abrupt('return', (0, (_mergeFiles || _load_mergeFiles()).default)(mergeFilesParams));

                      case 13:
                      case 'end':
                        return _context3.stop();
                    }
                  }
                }, _callee3, _this);
              }));

              return function (_x4) {
                return _ref4.apply(this, arguments);
              };
            }());
            return _context4.abrupt('return', Promise.all(conflictResultsP));

          case 3:
          case 'end':
            return _context4.stop();
        }
      }
    }, _callee4, this);
  }));

  return function getMergeResults(_x2, _x3) {
    return _ref3.apply(this, arguments);
  };
}();

var _ramda;

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

var _utils;

function _load_utils() {
  return _utils = require('../../../utils');
}

var _tmp;

function _load_tmp() {
  return _tmp = _interopRequireDefault(require('../../../scope/repositories/tmp'));
}

var _mergeFiles;

function _load_mergeFiles() {
  return _mergeFiles = _interopRequireDefault(require('../../../utils/merge-files'));
}

var _generalError;

function _load_generalError() {
  return _generalError = _interopRequireDefault(require('../../../error/general-error'));
}

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

exports.default = function () {
  var _ref = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee(_ref2) {
    var consumer = _ref2.consumer,
        otherComponent = _ref2.otherComponent,
        otherVersion = _ref2.otherVersion,
        currentComponent = _ref2.currentComponent,
        currentVersion = _ref2.currentVersion;
    var otherFiles, currentFiles, results, getFileResult, conflictResults;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            otherFiles = otherComponent.files;
            currentFiles = currentComponent.files;
            results = {
              addFiles: [],
              modifiedFiles: [],
              unModifiedFiles: [],
              overrideFiles: [],
              hasConflicts: false
            };

            getFileResult = function getFileResult(otherFile, currentFile) {
              var filePath = (0, (_utils || _load_utils()).pathNormalizeToLinux)(otherFile.relative);
              if (!currentFile) {
                results.addFiles.push({ filePath, otherFile });
                return;
              }
              var otherFileHash = (0, (_utils || _load_utils()).sha1)(otherFile.contents);
              var currentFileHash = (0, (_utils || _load_utils()).sha1)(currentFile.contents);
              if (otherFileHash === currentFileHash) {
                results.unModifiedFiles.push({ filePath, currentFile });
                return;
              }
              // it was changed in both, there is a chance for conflict
              currentFile.version = currentVersion;
              // $FlowFixMe it's a hack to pass the data, version is not a valid attribute.
              otherFile.version = otherVersion;
              results.modifiedFiles.push({ filePath, currentFile, otherFile, output: null, conflict: null });
            };

            otherFiles.forEach(function (otherFile) {
              var currentFile = currentFiles.find(function (file) {
                return file.relative === otherFile.relative;
              });
              getFileResult(otherFile, currentFile);
            });

            if (!(_ramda || _load_ramda()).default.isEmpty(results.modifiedFiles)) {
              _context.next = 7;
              break;
            }

            return _context.abrupt('return', results);

          case 7:
            _context.next = 9;
            return getMergeResults(consumer, results.modifiedFiles);

          case 9:
            conflictResults = _context.sent;

            conflictResults.forEach(function (conflictResult) {
              var modifiedFile = results.modifiedFiles.find(function (file) {
                return file.filePath === conflictResult.filePath;
              });
              if (!modifiedFile) throw new (_generalError || _load_generalError()).default(`unable to find ${conflictResult.filePath} in modified files array`);
              modifiedFile.output = conflictResult.output;
              modifiedFile.conflict = conflictResult.conflict;
              if (conflictResult.conflict) results.hasConflicts = true;
            });

            return _context.abrupt('return', results);

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

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

  return twoWayMergeVersions;
}();