'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var _Map2 = _interopDefault(require('babel-runtime/core-js/map'));
var _regeneratorRuntime = _interopDefault(require('babel-runtime/regenerator'));
var _asyncToGenerator = _interopDefault(require('babel-runtime/helpers/asyncToGenerator'));
var _Object$getPrototypeOf = _interopDefault(require('babel-runtime/core-js/object/get-prototype-of'));
var _classCallCheck = _interopDefault(require('babel-runtime/helpers/classCallCheck'));
var _createClass = _interopDefault(require('babel-runtime/helpers/createClass'));
var _possibleConstructorReturn = _interopDefault(require('babel-runtime/helpers/possibleConstructorReturn'));
var _inherits = _interopDefault(require('babel-runtime/helpers/inherits'));
var _getIterator = _interopDefault(require('babel-runtime/core-js/get-iterator'));
var commands = require('./commands.js');
var managers = require('./managers.js');
var models = require('./models.js');
var utils = require('./utils.js');

function git(dir) {
  return dir === undefined ? new Git() : new Git().workdir(dir).gitdir(dir + '/.git');
}
git.commands = commands;
git.managers = managers;
git.models = models;
git.utils = utils;

var extend = function extend(self, array) {
  var _loop = function _loop(fn) {
    self[fn] = function (val) {
      return self.set(fn, val);
    };
  };

  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = _getIterator(array), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var fn = _step.value;

      _loop(fn);
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }
};

// This is so git().relative() is the same as git().relative(true)
// but you can still undo the flag later with git().relative(false)
var extendBool = function extendBool(self, array) {
  var _loop2 = function _loop2(fn) {
    self[fn] = function (val) {
      return self.set(fn, val !== false);
    };
  };

  var _iteratorNormalCompletion2 = true;
  var _didIteratorError2 = false;
  var _iteratorError2 = undefined;

  try {
    for (var _iterator2 = _getIterator(array), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
      var fn = _step2.value;

      _loop2(fn);
    }
  } catch (err) {
    _didIteratorError2 = true;
    _iteratorError2 = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion2 && _iterator2.return) {
        _iterator2.return();
      }
    } finally {
      if (_didIteratorError2) {
        throw _iteratorError2;
      }
    }
  }
};

// The class is merely a fluent command/query builder

var Git = function (_Map) {
  _inherits(Git, _Map);

  // @constructor
  function Git(parent) {
    _classCallCheck(this, Git);

    var _this = _possibleConstructorReturn(this, (Git.__proto__ || _Object$getPrototypeOf(Git)).call(this, parent));

    extend(_this, ['workdir', 'gitdir', 'remote', 'branch', 'author', 'email', 'datetime', 'depth', 'since', 'exclude', 'timestamp', 'signingKey', 'verificationKey', 'username', 'password', 'url', 'outputStream', 'inputStream', 'onprogress']);
    extendBool(_this, ['relative']);
    return _this;
  }

  _createClass(Git, [{
    key: 'version',
    value: function version$$1() {
      return commands.version();
    }
    /**
     * @param {string} username
     * @param {string} password
     * @returns {Git} this
     *
     * Use with {@link #gitpush .push} and {@link #gitpull .pull} to set Basic Authentication headers.
     * This works for basic username / password auth, or the newer username / token auth
     * that is often required if 2FA is enabled.
     */

  }, {
    key: 'auth',
    value: function auth(username, password) {
      // Allow specifying it as one argument (mostly for CLI inputability)
      if (password === undefined) {
        var i = username.indexOf(':');
        if (i > -1) {
          password = username.slice(i + 1);
          username = username.slice(0, i);
        } else {
          password = ''; // Enables the .auth(GITHUB_TOKEN) no-username shorthand
        }
      }
      this.set('username', username);
      this.set('password', password);
      return this;
    }
    /**
     * @param {string} company
     * @param {string} token
     * @returns {Git} this
     *
     * Use with {@link #gitpush .push} and {@link #gitpull .pull} to set Basic Authentication headers.
     * This for is for *actual* OAuth2 tokens (not "personal access tokens").
     * Unfortunately, all the major git hosting companies have chosen different conventions!
     * Lucky for you, I already looked up and codified it for you.
     *
     * - oauth2('github', token) - Github uses `token` as the username, and 'x-oauth-basic' as the password.
     * - oauth2('bitbucket', token) - Bitbucket uses 'x-token-auth' as the username, and `token` as the password.
     * - oauth2('gitlab', token) - Gitlab uses 'oauth2' as the username, and `token` as the password.
     *
     * I will gladly accept pull requests for more companies' conventions.
     */

  }, {
    key: 'oauth2',
    value: function oauth2(company, token) {
      switch (company) {
        case 'github':
          this.set('username', token);
          this.set('password', 'x-oauth-basic');
          break;
        case 'bitbucket':
          this.set('username', 'x-token-auth');
          this.set('password', token);
          break;
        case 'gitlab':
          this.set('username', 'oauth2');
          this.set('password', token);
          break;
        default:
          throw new Error('I don\'t know how ' + company + ' expects its Basic Auth headers to be formatted for OAuth2 usage. If you do, you can use the regular \'.auth(username, password)\' to set the basic auth header yourself.');
      }
      return this;
    }
  }, {
    key: 'findRoot',
    value: function () {
      var _ref = _asyncToGenerator(_regeneratorRuntime.mark(function _callee(dir) {
        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                return _context.abrupt('return', commands.findRoot(dir));

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

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

      return findRoot$$1;
    }()
  }, {
    key: 'init',
    value: function () {
      var _ref2 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee2() {
        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                _context2.next = 2;
                return commands.init({
                  gitdir: this.get('gitdir')
                });

              case 2:
              case 'end':
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      function init$$1() {
        return _ref2.apply(this, arguments);
      }

      return init$$1;
    }()
  }, {
    key: 'fetch',
    value: function () {
      var _ref3 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee3(ref) {
        return _regeneratorRuntime.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                _context3.next = 2;
                return commands.fetch({
                  gitdir: this.get('gitdir'),
                  ref: ref,
                  url: this.get('url'),
                  remote: this.get('remote'),
                  authUsername: this.get('username'),
                  authPassword: this.get('password'),
                  depth: this.get('depth'),
                  since: this.get('since'),
                  exclude: this.get('exclude'),
                  relative: this.get('relative'),
                  onprogress: this.get('onprogress')
                });

              case 2:
              case 'end':
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      function fetch$$1(_x2) {
        return _ref3.apply(this, arguments);
      }

      return fetch$$1;
    }()
  }, {
    key: 'checkout',
    value: function () {
      var _ref4 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee4(ref) {
        return _regeneratorRuntime.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                _context4.next = 2;
                return commands.checkout({
                  workdir: this.get('workdir'),
                  gitdir: this.get('gitdir'),
                  ref: ref,
                  remote: this.get('remote')
                });

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

      function checkout$$1(_x3) {
        return _ref4.apply(this, arguments);
      }

      return checkout$$1;
    }()
  }, {
    key: 'clone',
    value: function () {
      var _ref5 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee5(url) {
        return _regeneratorRuntime.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                _context5.next = 2;
                return commands.clone({
                  workdir: this.get('workdir'),
                  gitdir: this.get('gitdir'),
                  url: url,
                  remote: this.get('remote'),
                  ref: this.get('branch'),
                  authUsername: this.get('username'),
                  authPassword: this.get('password'),
                  depth: this.get('depth'),
                  since: this.get('since'),
                  exclude: this.get('exclude'),
                  relative: this.get('relative'),
                  onprogress: this.get('onprogress')
                });

              case 2:
              case 'end':
                return _context5.stop();
            }
          }
        }, _callee5, this);
      }));

      function clone$$1(_x4) {
        return _ref5.apply(this, arguments);
      }

      return clone$$1;
    }()
  }, {
    key: 'list',
    value: function () {
      var _ref6 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee6() {
        return _regeneratorRuntime.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                return _context6.abrupt('return', commands.list({
                  gitdir: this.get('gitdir')
                }));

              case 1:
              case 'end':
                return _context6.stop();
            }
          }
        }, _callee6, this);
      }));

      function list$$1() {
        return _ref6.apply(this, arguments);
      }

      return list$$1;
    }()
  }, {
    key: 'log',
    value: function () {
      var _ref7 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee7(ref) {
        return _regeneratorRuntime.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                return _context7.abrupt('return', commands.log({
                  gitdir: this.get('gitdir'),
                  ref: ref,
                  depth: this.get('depth'),
                  since: this.get('since')
                }));

              case 1:
              case 'end':
                return _context7.stop();
            }
          }
        }, _callee7, this);
      }));

      function log$$1(_x5) {
        return _ref7.apply(this, arguments);
      }

      return log$$1;
    }()
  }, {
    key: 'add',
    value: function () {
      var _ref8 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee8(filepath) {
        return _regeneratorRuntime.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                return _context8.abrupt('return', commands.add({
                  gitdir: this.get('gitdir'),
                  workdir: this.get('workdir'),
                  filepath: filepath
                }));

              case 1:
              case 'end':
                return _context8.stop();
            }
          }
        }, _callee8, this);
      }));

      function add$$1(_x6) {
        return _ref8.apply(this, arguments);
      }

      return add$$1;
    }()
  }, {
    key: 'remove',
    value: function () {
      var _ref9 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee9(filepath) {
        return _regeneratorRuntime.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                return _context9.abrupt('return', commands.remove({
                  gitdir: this.get('gitdir'),
                  filepath: filepath
                }));

              case 1:
              case 'end':
                return _context9.stop();
            }
          }
        }, _callee9, this);
      }));

      function remove$$1(_x7) {
        return _ref9.apply(this, arguments);
      }

      return remove$$1;
    }()
  }, {
    key: 'commit',
    value: function () {
      var _ref10 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee10(message) {
        return _regeneratorRuntime.wrap(function _callee10$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                return _context10.abrupt('return', commands.commit({
                  gitdir: this.get('gitdir'),
                  author: {
                    name: this.get('author'),
                    email: this.get('email'),
                    timestamp: this.get('timestamp'),
                    date: this.get('datetime')
                  },
                  committer: {
                    name: this.get('author'),
                    email: this.get('email'),
                    timestamp: this.get('timestamp'),
                    date: this.get('datetime')
                  },
                  message: message,
                  privateKeys: this.get('signingKey')
                }));

              case 1:
              case 'end':
                return _context10.stop();
            }
          }
        }, _callee10, this);
      }));

      function commit$$1(_x8) {
        return _ref10.apply(this, arguments);
      }

      return commit$$1;
    }()
  }, {
    key: 'verify',
    value: function () {
      var _ref11 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee11(ref) {
        return _regeneratorRuntime.wrap(function _callee11$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                return _context11.abrupt('return', commands.verify({
                  gitdir: this.get('gitdir'),
                  publicKeys: this.get('verificationKey'),
                  ref: ref
                }));

              case 1:
              case 'end':
                return _context11.stop();
            }
          }
        }, _callee11, this);
      }));

      function verify$$1(_x9) {
        return _ref11.apply(this, arguments);
      }

      return verify$$1;
    }()
  }, {
    key: 'pack',
    value: function () {
      var _ref12 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee12(oids) {
        return _regeneratorRuntime.wrap(function _callee12$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                return _context12.abrupt('return', commands.pack({
                  gitdir: this.get('gitdir'),
                  outputStream: this.get('outputStream'),
                  oids: oids
                }));

              case 1:
              case 'end':
                return _context12.stop();
            }
          }
        }, _callee12, this);
      }));

      function pack$$1(_x10) {
        return _ref12.apply(this, arguments);
      }

      return pack$$1;
    }()
  }, {
    key: 'unpack',
    value: function () {
      var _ref13 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee13(oids) {
        return _regeneratorRuntime.wrap(function _callee13$(_context13) {
          while (1) {
            switch (_context13.prev = _context13.next) {
              case 0:
                return _context13.abrupt('return', commands.unpack({
                  gitdir: this.get('gitdir'),
                  inputStream: this.get('inputStream')
                }));

              case 1:
              case 'end':
                return _context13.stop();
            }
          }
        }, _callee13, this);
      }));

      function unpack$$1(_x11) {
        return _ref13.apply(this, arguments);
      }

      return unpack$$1;
    }()
  }, {
    key: 'push',
    value: function () {
      var _ref14 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee14(ref) {
        return _regeneratorRuntime.wrap(function _callee14$(_context14) {
          while (1) {
            switch (_context14.prev = _context14.next) {
              case 0:
                return _context14.abrupt('return', commands.push({
                  gitdir: this.get('gitdir'),
                  ref: ref,
                  remote: this.get('remote'),
                  url: this.get('url'),
                  authUsername: this.get('username'),
                  authPassword: this.get('password')
                }));

              case 1:
              case 'end':
                return _context14.stop();
            }
          }
        }, _callee14, this);
      }));

      function push$$1(_x12) {
        return _ref14.apply(this, arguments);
      }

      return push$$1;
    }()
  }, {
    key: 'pull',
    value: function () {
      var _ref15 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee15(ref) {
        return _regeneratorRuntime.wrap(function _callee15$(_context15) {
          while (1) {
            switch (_context15.prev = _context15.next) {
              case 0:
                return _context15.abrupt('return', commands.fetch({
                  gitdir: this.get('gitdir'),
                  ref: ref,
                  remote: this.get('remote'),
                  authUsername: this.get('username'),
                  authPassword: this.get('password')
                }));

              case 1:
              case 'end':
                return _context15.stop();
            }
          }
        }, _callee15, this);
      }));

      function pull(_x13) {
        return _ref15.apply(this, arguments);
      }

      return pull;
    }()
  }, {
    key: 'config',
    value: function () {
      var _ref16 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee16(path, value) {
        var _args16 = arguments;
        return _regeneratorRuntime.wrap(function _callee16$(_context16) {
          while (1) {
            switch (_context16.prev = _context16.next) {
              case 0:
                if (!(_args16.length === 1)) {
                  _context16.next = 4;
                  break;
                }

                return _context16.abrupt('return', commands.config({
                  gitdir: this.get('gitdir'),
                  path: path
                }));

              case 4:
                return _context16.abrupt('return', commands.config({
                  gitdir: this.get('gitdir'),
                  path: path,
                  value: value
                }));

              case 5:
              case 'end':
                return _context16.stop();
            }
          }
        }, _callee16, this);
      }));

      function config$$1(_x14, _x15) {
        return _ref16.apply(this, arguments);
      }

      return config$$1;
    }()
  }, {
    key: 'status',
    value: function () {
      var _ref17 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee17(pathname) {
        return _regeneratorRuntime.wrap(function _callee17$(_context17) {
          while (1) {
            switch (_context17.prev = _context17.next) {
              case 0:
                return _context17.abrupt('return', commands.status({
                  gitdir: this.get('gitdir'),
                  workdir: this.get('workdir'),
                  pathname: pathname
                }));

              case 1:
              case 'end':
                return _context17.stop();
            }
          }
        }, _callee17, this);
      }));

      function status$$1(_x16) {
        return _ref17.apply(this, arguments);
      }

      return status$$1;
    }()
  }, {
    key: 'listBranches',
    value: function () {
      var _ref18 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee18() {
        return _regeneratorRuntime.wrap(function _callee18$(_context18) {
          while (1) {
            switch (_context18.prev = _context18.next) {
              case 0:
                return _context18.abrupt('return', commands.listBranches({
                  gitdir: this.get('gitdir')
                }));

              case 1:
              case 'end':
                return _context18.stop();
            }
          }
        }, _callee18, this);
      }));

      function listBranches$$1() {
        return _ref18.apply(this, arguments);
      }

      return listBranches$$1;
    }()
  }]);

  return Git;
}(_Map2);

module.exports = git;
//# sourceMappingURL=index.js.map
