'use strict';

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

var _regenerator;

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

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _ramda;

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

var _utils;

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

var _constants;

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

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"); }); }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var BitRawObject = function () {
  function BitRawObject(buffer, ref, types, type, content, parsedContent) {
    _classCallCheck(this, BitRawObject);

    var headers = void 0;
    var contentFromBuffer = void 0;
    if (buffer) {
      var firstNullByteLocation = buffer.indexOf((_constants || _load_constants()).NULL_BYTE);
      headers = buffer.slice(0, firstNullByteLocation).toString();
      contentFromBuffer = buffer.slice(firstNullByteLocation + 1, buffer.length);
    }
    this.content = content || contentFromBuffer;
    this.headers = headers ? headers.split((_constants || _load_constants()).SPACE_DELIMITER) : undefined;
    var typeFromHeader = this.headers ? this.headers[0] : undefined;
    this.type = type || typeFromHeader;
    this._ref = ref;
    this.types = types;
    this.parsedContent = parsedContent || this.getParsedContent();
  }

  _createClass(BitRawObject, [{
    key: 'getParsedContent',
    value: function getParsedContent() {
      if (this.parsedContent) return this.parsedContent;
      var parsedContent = void 0;
      switch (this.type) {
        case 'Version':
        case 'Component':
        case 'Symlink':
        case 'ScopeMeta':
          parsedContent = JSON.parse(this.content.toString());
          break;

        default:
          parsedContent = this.content;
      }
      return parsedContent;
    }
  }, {
    key: 'getString',
    value: function getString(pretty) {
      var args = (0, (_utils || _load_utils()).getStringifyArgs)(pretty);
      switch (this.type) {
        case 'Version':
        case 'Component':
        case 'Symlink':
        case 'ScopeMeta':
          return JSON.stringify.apply(JSON, [this.parsedContent].concat(_toConsumableArray(args)));

        default:
          return this.content;
      }
    }
  }, {
    key: 'refs',
    value: function refs() {
      if (this.type === 'Component') {
        return (_ramda || _load_ramda()).default.values(this.parsedContent.versions);
      }
      if (this.type === 'Version') {
        var files = this.parsedContent.files ? this.parsedContent.files.map(function (file) {
          return file.file;
        }) : [];
        var dists = this.parsedContent.dists ? this.parsedContent.dists.map(function (dist) {
          return dist.file;
        }) : [];
        return [].concat(_toConsumableArray(dists), _toConsumableArray(files)).filter(function (ref) {
          return ref;
        });
      }

      return [];
    }
  }, {
    key: 'toRealObject',


    /**
     * Build a real object (model) from a parsed content (can be the original parsed conents or a provided one)
     * We use the provided version during the migration process when we change the parsed content outside
     * @param {Any} parsedContent
     */
    value: function toRealObject() {
      return this.types[this.type].from(this.parsedContent || this.getParsedContent());
    }
  }, {
    key: 'clone',
    value: function clone() {
      var types = this.types ? (_ramda || _load_ramda()).default.clone(this.types) : undefined;
      var parsedContent = this.parsedContent ? (_ramda || _load_ramda()).default.clone(this.parsedContent) : undefined;
      // TODO: Should also clone the buffers (content)
      return new BitRawObject(undefined, this._ref, types, this.type, this.content, parsedContent);
    }
  }, {
    key: 'ref',
    set: function set(ref) {
      this._ref = ref;
    },
    get: function get() {
      return this._ref;
    }
  }, {
    key: 'id',
    get: function get() {
      switch (this.type) {
        case 'Version':
          return 'component version';
        case 'Component':
          return this.parsedContent.scope ? [this.parsedContent.scope, this.parsedContent.name].join('/') : this.parsedContent.name;
        case 'Symlink':
          return this.parsedContent.name;
        case 'ScopeMeta':
          return this.parsedContent.name;

        default:
          return 'component source file';
      }
    }
  }], [{
    key: 'fromDeflatedBuffer',
    value: function () {
      var _ref = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee(fileContents, ref, types) {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                return _context.abrupt('return', (0, (_utils || _load_utils()).inflate)(fileContents).then(function (buffer) {
                  return new BitRawObject(buffer, ref, types);
                }));

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

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

      return fromDeflatedBuffer;
    }()
  }]);

  return BitRawObject;
}();

exports.default = BitRawObject;