const path = require('path');
const union = require('lodash').union;
const last = require('lodash').last;

/**
 * Given an array of directories, it returns the one that contains
 * all the other directories in a given array inside it.
 *
 * Example:
 * Given an array of directories: ['/Users/Kureev/a', '/Users/Kureev/b']
 * the returned folder is `/Users/Kureev`
 *
 * Check `getHeaderSearchPath.spec.js` for more use-cases.
 */
const getOuterDirectory = (directories) =>
  directories.reduce((topDir, currentDir) => {
    const currentFolders = currentDir.split(path.sep);
    const topMostFolders = topDir.split(path.sep);

    if (currentFolders.length === topMostFolders.length
      && last(currentFolders) !== last(topMostFolders)) {
      return currentFolders.slice(0, -1).join(path.sep);
    }

    return currentFolders.length < topMostFolders.length
      ? currentDir
      : topDir;
  });

/**
 * Given an array of headers it returns search path so Xcode can resolve
 * headers when referenced like below:
 * ```
 * #import "CodePush.h"
 * ```
 * If all files are located in one directory (directories.length === 1),
 * we simply return a relative path to that location.
 *
 * Otherwise, we loop through them all to find the outer one that contains
 * all the headers inside. That location is then returned with /** appended at
 * the end so Xcode marks that location as `recursive` and will look inside
 * every folder of it to locate correct headers.
 */
module.exports = function getHeaderSearchPath(sourceDir, headers) {
  const directories = union(
    headers.map(path.dirname)
  );

  return directories.length === 1
    ? `"$(SRCROOT)${path.sep}${path.relative(sourceDir, directories[0])}"`
    : `"$(SRCROOT)${path.sep}${path.relative(sourceDir, getOuterDirectory(directories))}/**"`;
};
