"use strict";

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

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

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 _componentMap() {
  const data = _interopRequireDefault(require("../../bit-map/component-map"));

  _componentMap = function () {
    return data;
  };

  return data;
}

function _exceptions() {
  const data = require("../../bit-map/exceptions");

  _exceptions = function () {
    return data;
  };

  return data;
}

function _constants() {
  const data = require("../../../constants");

  _constants = function () {
    return data;
  };

  return data;
}

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

  _path2 = function () {
    return data;
  };

  return data;
}

function determineMainFile(addedComponent, existingComponentMap) {
  const mainFile = addedComponent.mainFile;
  const componentIdStr = addedComponent.componentId.toString();
  const files = addedComponent.files.filter(file => !file.test);
  const rootDir = existingComponentMap && existingComponentMap.rootDir;
  const strategies = [getExistingIfNotChanged, getUserSpecifiedMainFile, onlyOneFileEnteredUseIt, searchForFileNameIndex, searchForSameFileNameAsImmediateDir];

  for (const strategy of strategies) {
    const foundMainFile = strategy();

    if (foundMainFile) {
      return foundMainFile;
    }
  }

  const mainFileString = `${_constants().DEFAULT_INDEX_NAME}.[${_constants().DEFAULT_INDEX_EXTS.join(', ')}]`;
  throw new (_exceptions().MissingMainFile)(componentIdStr, mainFileString, files.map(file => _path().default.normalize(file.relativePath)));
  /**
   * user didn't enter mainFile but the component already exists with mainFile
   */

  function getExistingIfNotChanged() {
    if (!mainFile && existingComponentMap) {
      return existingComponentMap.mainFile;
    }

    return null;
  }
  /**
   * user entered mainFile => search the mainFile in the files array, throw error if not found
   */


  function getUserSpecifiedMainFile() {
    if (mainFile) {
      const foundMainFile = _searchMainFile((0, _path2().pathNormalizeToLinux)(mainFile));

      if (foundMainFile) return foundMainFile;
      throw new (_exceptions().MissingMainFile)(componentIdStr, mainFile, files.map(file => _path().default.normalize(file.relativePath)));
    }

    return null;
  }
  /**
   * user didn't enter mainFile and the component has only one file, use that file as the main file
   */


  function onlyOneFileEnteredUseIt() {
    if (files.length === 1) {
      return files[0].relativePath;
    }

    return null;
  }
  /**
   * user didn't enter mainFile and the component has multiple files, search for file name "index",
   * e.g. `index.js`, `index.css`, etc.
   */


  function searchForFileNameIndex() {
    for (const ext of _constants().DEFAULT_INDEX_EXTS) {
      const mainFileNameToSearch = `${_constants().DEFAULT_INDEX_NAME}.${ext}`;

      const searchResult = _searchMainFile(mainFileNameToSearch);

      if (searchResult) {
        return searchResult;
      }
    }

    return null;
  }
  /**
   * user didn't enter mainFile and the component has multiple files, search for file with the same
   * name as the directory (see #1714)
   */


  function searchForSameFileNameAsImmediateDir() {
    if (addedComponent.immediateDir) {
      for (const ext of _constants().DEFAULT_INDEX_EXTS) {
        const mainFileNameToSearch = `${addedComponent.immediateDir}.${ext}`;

        const searchResult = _searchMainFile(mainFileNameToSearch);

        if (searchResult) {
          return searchResult;
        }
      }
    }

    return null;
  }

  function _searchMainFile(baseMainFile) {
    // search for an exact relative-path
    let mainFileFromFiles = files.find(file => file.relativePath === baseMainFile);
    if (mainFileFromFiles) return baseMainFile;

    if (rootDir) {
      const mainFileUsingRootDir = files.find(file => (0, _path2().pathJoinLinux)(rootDir, file.relativePath) === baseMainFile);
      if (mainFileUsingRootDir) return mainFileUsingRootDir.relativePath;
    } // search for a file-name


    const potentialMainFiles = files.filter(file => file.name === baseMainFile);
    if (!potentialMainFiles.length) return null; // when there are several files that met the criteria, choose the closer to the root

    const sortByNumOfDirs = (a, b) => a.relativePath.split(_constants().DEFAULT_SEPARATOR).length - b.relativePath.split(_constants().DEFAULT_SEPARATOR).length;

    potentialMainFiles.sort(sortByNumOfDirs);
    mainFileFromFiles = _ramda().default.head(potentialMainFiles);
    return mainFileFromFiles.relativePath;
  }
}