'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 _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

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 _fsExtra;

function _load_fsExtra() {
  return _fsExtra = _interopRequireDefault(require('fs-extra'));
}

var _path;

function _load_path() {
  return _path = _interopRequireDefault(require('path'));
}

var _ramda;

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

var _detectIndent;

function _load_detectIndent() {
  return _detectIndent = _interopRequireDefault(require('detect-indent'));
}

var _constants;

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

var _jsonFile;

function _load_jsonFile() {
  return _jsonFile = _interopRequireDefault(require('./sources/json-file'));
}

var _logger;

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

var _consumerComponent;

function _load_consumerComponent() {
  return _consumerComponent = _interopRequireDefault(require('./consumer-component'));
}

var _componentIdToPackageName;

function _load_componentIdToPackageName() {
  return _componentIdToPackageName = _interopRequireDefault(require('../../utils/bit/component-id-to-package-name'));
}

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

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

var PackageJsonFile = function () {
  function PackageJsonFile(filePath, packageJsonObject, fileExist, indent) {
    _classCallCheck(this, PackageJsonFile);

    this.filePath = filePath;
    this.packageJsonObject = packageJsonObject;
    this.fileExist = fileExist;
    this.indent = indent || (_constants || _load_constants()).PACKAGE_JSON_DEFAULT_INDENT;
  }

  _createClass(PackageJsonFile, [{
    key: 'write',
    value: function () {
      var _ref = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee() {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                (_logger || _load_logger()).default.debug(`package-json-file.write, path ${this.filePath}`);
                return _context.abrupt('return', (_fsExtra || _load_fsExtra()).default.outputJSON(this.filePath, this.packageJsonObject, { spaces: this.indent }));

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

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

      return write;
    }()

    /**
     * load from the given dir, if not exist, don't throw an error, just set packageJsonObject as an
     * empty object
     */

  }, {
    key: 'toJSONFile',
    value: function toJSONFile() {
      return (_jsonFile || _load_jsonFile()).default.load({
        base: (_path || _load_path()).default.dirname(this.filePath),
        path: this.filePath,
        content: this.packageJsonObject,
        indent: this.indent,
        override: true
      });
    }
  }, {
    key: 'addDependencies',
    value: function addDependencies(dependencies) {
      this.packageJsonObject.dependencies = Object.assign({}, this.packageJsonObject.dependencies, dependencies);
    }
  }, {
    key: 'addDevDependencies',
    value: function addDevDependencies(dependencies) {
      this.packageJsonObject.devDependencies = Object.assign({}, this.packageJsonObject.devDependencies, dependencies);
    }
  }, {
    key: 'addOrUpdateProperty',
    value: function addOrUpdateProperty(propertyName, propertyValue) {
      this.packageJsonObject[propertyName] = propertyValue;
    }
  }, {
    key: 'getProperty',
    value: function getProperty(propertyName) {
      return this.packageJsonObject[propertyName];
    }
  }], [{
    key: 'load',
    value: function () {
      var _ref2 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2(dir) {
        var filePath, packageJsonStr, packageJsonObject, indent;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                filePath = composePath(dir);
                _context2.next = 3;
                return PackageJsonFile.getPackageJsonStrIfExist(filePath);

              case 3:
                packageJsonStr = _context2.sent;

                if (packageJsonStr) {
                  _context2.next = 6;
                  break;
                }

                return _context2.abrupt('return', new PackageJsonFile(filePath, {}, false));

              case 6:
                packageJsonObject = PackageJsonFile.parsePackageJsonStr(packageJsonStr, dir);
                indent = (0, (_detectIndent || _load_detectIndent()).default)(packageJsonStr).amount;
                return _context2.abrupt('return', new PackageJsonFile(filePath, packageJsonObject, true, indent));

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

      function load(_x) {
        return _ref2.apply(this, arguments);
      }

      return load;
    }()
  }, {
    key: 'create',
    value: function create(dir, packageJsonObject) {
      var filePath = composePath(dir);
      return new PackageJsonFile(filePath, packageJsonObject, false);
    }
  }, {
    key: 'createFromComponent',
    value: function createFromComponent(dir, component) {
      var excludeRegistryPrefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;

      var filePath = composePath(dir);
      var name = excludeRegistryPrefix ? (0, (_componentIdToPackageName || _load_componentIdToPackageName()).default)(component.id, component.bindingPrefix, false) : (0, (_componentIdToPackageName || _load_componentIdToPackageName()).default)(component.id, component.bindingPrefix);
      var packageJsonObject = {
        name,
        version: component.version,
        homepage: component._getHomepage(),
        main: component.mainFile,
        dependencies: component.packageDependencies,
        devDependencies: _extends({}, component.devPackageDependencies, component.compilerPackageDependencies, component.testerPackageDependencies),
        peerDependencies: component.peerPackageDependencies,
        license: `SEE LICENSE IN ${!(_ramda || _load_ramda()).default.isEmpty(component.license) ? 'LICENSE' : 'UNLICENSED'}`
      };
      return new PackageJsonFile(filePath, packageJsonObject, false);
    }
  }, {
    key: 'parsePackageJsonStr',
    value: function parsePackageJsonStr(str, dir) {
      try {
        return JSON.parse(str);
      } catch (err) {
        throw new Error(`failed parsing package.json file at ${dir}. original error: ${err.message}`);
      }
    }
  }, {
    key: 'getPackageJsonStrIfExist',
    value: function () {
      var _ref3 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3(filePath) {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                _context3.prev = 0;
                _context3.next = 3;
                return (_fsExtra || _load_fsExtra()).default.readFile(filePath, 'utf-8');

              case 3:
                return _context3.abrupt('return', _context3.sent);

              case 6:
                _context3.prev = 6;
                _context3.t0 = _context3['catch'](0);

                if (!(_context3.t0.code === 'ENOENT')) {
                  _context3.next = 10;
                  break;
                }

                return _context3.abrupt('return', null);

              case 10:
                throw _context3.t0;

              case 11:
              case 'end':
                return _context3.stop();
            }
          }
        }, _callee3, this, [[0, 6]]);
      }));

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

      return getPackageJsonStrIfExist;
    }()
  }]);

  return PackageJsonFile;
}();

exports.default = PackageJsonFile;


function composePath(componentRootFolder) {
  return (_path || _load_path()).default.join(componentRootFolder, (_constants || _load_constants()).PACKAGE_JSON);
}