"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

function _bluebird() {
  const data = require("bluebird");

  _bluebird = function () {
    return data;
  };

  return data;
}

function _path() {
  const data = _interopRequireDefault(require("path"));

  _path = function () {
    return data;
  };

  return data;
}

function _ramda() {
  const data = _interopRequireDefault(require("ramda"));

  _ramda = function () {
    return data;
  };

  return data;
}

function _vinylFile() {
  const data = _interopRequireDefault(require("vinyl-file"));

  _vinylFile = function () {
    return data;
  };

  return data;
}

function _sources() {
  const data = require("../consumer/component/sources");

  _sources = function () {
    return data;
  };

  return data;
}

function _extensionFileNotFound() {
  const data = _interopRequireDefault(require("./exceptions/extension-file-not-found"));

  _extensionFileNotFound = function () {
    return data;
  };

  return data;
}

function _logger() {
  const data = _interopRequireDefault(require("../logger/logger"));

  _logger = function () {
    return data;
  };

  return data;
}

function _objects() {
  const data = require("../scope/objects");

  _objects = function () {
    return data;
  };

  return data;
}

function _source() {
  const data = _interopRequireDefault(require("../scope/models/source"));

  _source = function () {
    return data;
  };

  return data;
}

function _path2() {
  const data = require("../utils/path");

  _path2 = function () {
    return data;
  };

  return data;
}

class ExtensionFile extends _sources().AbstractVinyl {
  static load(name, filePath, consumerPath, base = consumerPath, extendedProps) {
    return (0, _bluebird().coroutine)(function* () {
      try {
        const baseFile = yield _vinylFile().default.read(filePath, {
          base,
          cwd: consumerPath
        });
        const file = new ExtensionFile(baseFile);
        file.name = name;
        file.file = _source().default.from(file.contents);

        const addToFile = (value, key) => file[key] = value;
        /* eslint-disable-line no-return-assign */


        _ramda().default.forEachObjIndexed(addToFile, extendedProps);

        return file;
      } catch (err) {
        _logger().default.error(`failed loading file ${filePath}. Error: ${err}`);

        if (err.code === 'ENOENT' && err.path) {
          throw new (_extensionFileNotFound().default)(err.path);
        }

        throw err;
      }
    })();
  }

  static loadFromBitJsonObject(bitJsonObj, consumerPath, bitJsonDirPath, envType) {
    var _this = this;

    return (0, _bluebird().coroutine)(function* () {
      if (!bitJsonObj || _ramda().default.isEmpty(bitJsonObj)) return [];
      const loadP = []; // for non-envs extension, the base is the consumer root.
      // for envs, bit.json may have "{ENV_TYPE}" in its "ejectedEnvsDirectory" configuration, when
      // this happens, the base dir includes the env-type. e.g. base-dir/compiler or base/dir-tester
      // @todo 1: make sure relativePath is PathLinux
      // @todo 2: pass the 'ejectedEnvsDirectory' and work according to its value. the implementation
      // below won't work well if a user decided to name the compiler folder as 'compiler' without
      // using {ENV_TYPE} notation.

      const getBase = relativePath => {
        if (!envType) return consumerPath;
        const pathSplit = relativePath.split('/');
        const envRelativePath = pathSplit[0] === '.' ? _ramda().default.tail(pathSplit) : pathSplit;

        const potentialEnvTypePlaceholder = _ramda().default.head(envRelativePath);

        if (potentialEnvTypePlaceholder === envType && envRelativePath.length > 1) {
          return _path().default.join(bitJsonDirPath, envType);
        }

        return bitJsonDirPath;
      };

      const loadFile = (value, key) => {
        // TODO: Gilad - support component bit json
        const fullPath = _path().default.resolve(bitJsonDirPath, value);

        const base = getBase(value);
        loadP.push(_this.load(key, fullPath, bitJsonDirPath, base));
      };

      _ramda().default.forEachObjIndexed(loadFile, bitJsonObj);

      return Promise.all(loadP);
    })();
  }

  static loadFromParsedString(parsedString) {
    if (!parsedString) return null;
    const opts = super.loadFromParsedString(parsedString);
    const extensionFile = new ExtensionFile(opts);
    extensionFile.file = _source().default.from(extensionFile.contents);
    return extensionFile;
  }

  static loadFromParsedStringArray(arr) {
    if (!arr) return null;
    return arr.map(this.loadFromParsedString);
  }

  static loadFromExtensionFileModel(file, repository) {
    return (0, _bluebird().coroutine)(function* () {
      // $FlowFixMe
      const content = yield file.file.load(repository);
      const extensionFile = new ExtensionFile({
        base: '.',
        path: file.relativePath,
        contents: content.contents
      });
      extensionFile.file = _source().default.from(extensionFile.contents);
      extensionFile.name = file.name;
      extensionFile.relativePath = file.relativePath;
      extensionFile.fromModel = true;
      return extensionFile;
    })();
  }
  /**
   * Used when running bit show against remote scope
   * @param {*} file
   * @param {*} repository
   */


  static loadFromExtensionFileSerializedModel(file) {
    return (0, _bluebird().coroutine)(function* () {
      const contents = Buffer.from(file.file.contents);
      const extensionFile = new ExtensionFile({
        base: '.',
        path: file.relativePath || '',
        contents
      });
      extensionFile.file = _source().default.from(extensionFile.contents);
      extensionFile.name = file.name;
      extensionFile.relativePath = file.relativePath;
      extensionFile.fromModel = true;
      return extensionFile;
    })();
  }
  /**
   * Util function to transform the file from Ref to string
   * Used in version.toObject
   * The opposite action of fromObjectToModelObject
   * @param {*} file
   */


  static fromModelObjectToObject(file) {
    return {
      name: file.name,
      relativePath: file.relativePath,
      file: file.file.toString()
    };
  }
  /**
   * Util function to transform the file from string to Ref
   * Used in version.parse
   * The opposite action of fromModelObjectToObject
   * @param {*} file
   */


  static fromObjectToModelObject(file) {
    return {
      name: file.name,
      relativePath: file.relativePath,
      file: new (_objects().Ref)(file.file)
    };
  }
  /**
   * Transform an instance of extension file to model object
   * (before storing in the models)
   */


  toModelObject() {
    return {
      name: this.name,
      relativePath: (0, _path2().pathNormalizeToLinux)(this.relative),
      file: this.file.hash()
    };
  }

  toReadableString() {
    return {
      name: this.name,
      content: this.contents.toString()
    };
  }

  clone() {
    return new ExtensionFile(this);
  }

}

exports.default = ExtensionFile;