/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmSourceGroupCommand.h"

#include <algorithm>
#include <set>
#include <stddef.h>
#include <utility>

#include "cmMakefile.h"
#include "cmSourceGroup.h"
#include "cmSystemTools.h"

namespace {
const std::string kTreeOptionName = "TREE";
const std::string kPrefixOptionName = "PREFIX";
const std::string kFilesOptionName = "FILES";
const std::string kRegexOptionName = "REGULAR_EXPRESSION";
const std::string kSourceGroupOptionName = "<sg_name>";

std::vector<std::string> tokenizePath(const std::string& path)
{
  return cmSystemTools::tokenize(path, "\\/");
}

std::string getFullFilePath(const std::string& currentPath,
                            const std::string& path)
{
  std::string fullPath = path;

  if (!cmSystemTools::FileIsFullPath(path)) {
    fullPath = currentPath;
    fullPath += "/";
    fullPath += path;
  }

  return cmSystemTools::CollapseFullPath(fullPath);
}

std::set<std::string> getSourceGroupFilesPaths(
  const std::string& root, const std::vector<std::string>& files)
{
  std::set<std::string> ret;
  const std::string::size_type rootLength = root.length();

  for (std::string const& file : files) {
    ret.insert(file.substr(rootLength + 1)); // +1 to also omnit last '/'
  }

  return ret;
}

bool rootIsPrefix(const std::string& root,
                  const std::vector<std::string>& files, std::string& error)
{
  for (std::string const& file : files) {
    if (!cmSystemTools::StringStartsWith(file, root.c_str())) {
      error = "ROOT: " + root + " is not a prefix of file: " + file;
      return false;
    }
  }

  return true;
}

std::string prepareFilePathForTree(const std::string& path,
                                   const std::string& currentSourceDir)
{
  if (!cmSystemTools::FileIsFullPath(path)) {
    return cmSystemTools::CollapseFullPath(currentSourceDir + "/" + path);
  }
  return cmSystemTools::CollapseFullPath(path);
}

std::vector<std::string> prepareFilesPathsForTree(
  const std::vector<std::string>& filesPaths,
  const std::string& currentSourceDir)
{
  std::vector<std::string> prepared;
  prepared.reserve(filesPaths.size());

  for (auto const& filePath : filesPaths) {
    // If provided file path is actually not a file, silently ignore it.
    if (cmSystemTools::FileExists(filePath, /*isFile=*/true)) {
      prepared.push_back(prepareFilePathForTree(filePath, currentSourceDir));
    }
  }

  return prepared;
}

bool addFilesToItsSourceGroups(const std::string& root,
                               const std::set<std::string>& sgFilesPaths,
                               const std::string& prefix, cmMakefile& makefile,
                               std::string& errorMsg)
{
  cmSourceGroup* sg;

  for (std::string const& sgFilesPath : sgFilesPaths) {

    std::vector<std::string> tokenizedPath;
    if (!prefix.empty()) {
      tokenizedPath = tokenizePath(prefix + '/' + sgFilesPath);
    } else {
      tokenizedPath = tokenizePath(sgFilesPath);
    }

    if (!tokenizedPath.empty()) {
      tokenizedPath.pop_back();

      if (tokenizedPath.empty()) {
        tokenizedPath.emplace_back();
      }

      sg = makefile.GetOrCreateSourceGroup(tokenizedPath);

      if (!sg) {
        errorMsg = "Could not create source group for file: " + sgFilesPath;
        return false;
      }
      const std::string fullPath = getFullFilePath(root, sgFilesPath);
      sg->AddGroupFile(fullPath);
    }
  }

  return true;
}
}

class cmExecutionStatus;

// cmSourceGroupCommand
cmSourceGroupCommand::ExpectedOptions
cmSourceGroupCommand::getExpectedOptions() const
{
  ExpectedOptions options;

  options.push_back(kTreeOptionName);
  options.push_back(kPrefixOptionName);
  options.push_back(kFilesOptionName);
  options.push_back(kRegexOptionName);

  return options;
}

bool cmSourceGroupCommand::isExpectedOption(
  const std::string& argument, const ExpectedOptions& expectedOptions)
{
  return std::find(expectedOptions.begin(), expectedOptions.end(), argument) !=
    expectedOptions.end();
}

void cmSourceGroupCommand::parseArguments(
  const std::vector<std::string>& args,
  cmSourceGroupCommand::ParsedArguments& parsedArguments)
{
  const ExpectedOptions expectedOptions = getExpectedOptions();
  size_t i = 0;

  // at this point we know that args vector is not empty

  // if first argument is not one of expected options it's source group name
  if (!isExpectedOption(args[0], expectedOptions)) {
    // get source group name and go to next argument
    parsedArguments[kSourceGroupOptionName].push_back(args[0]);
    ++i;
  }

  for (; i < args.size();) {
    // get current option and increment index to go to next argument
    const std::string& currentOption = args[i++];

    // create current option entry in parsed arguments
    std::vector<std::string>& currentOptionArguments =
      parsedArguments[currentOption];

    // collect option arguments while we won't find another expected option
    while (i < args.size() && !isExpectedOption(args[i], expectedOptions)) {
      currentOptionArguments.push_back(args[i++]);
    }
  }
}

bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
                                       cmExecutionStatus&)
{
  if (args.empty()) {
    this->SetError("called with incorrect number of arguments");
    return false;
  }

  // If only two arguments are given, the pre-1.8 version of the
  // command is being invoked.
  if (args.size() == 2 && args[1] != "FILES") {
    cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]);

    if (!sg) {
      this->SetError("Could not create or find source group");
      return false;
    }

    sg->SetGroupRegex(args[1].c_str());
    return true;
  }

  ParsedArguments parsedArguments;
  std::string errorMsg;

  parseArguments(args, parsedArguments);

  if (!checkArgumentsPreconditions(parsedArguments, errorMsg)) {
    return false;
  }

  if (parsedArguments.find(kTreeOptionName) != parsedArguments.end()) {
    if (!processTree(parsedArguments, errorMsg)) {
      this->SetError(errorMsg);
      return false;
    }
  } else {
    if (parsedArguments.find(kSourceGroupOptionName) ==
        parsedArguments.end()) {
      this->SetError("Missing source group name.");
      return false;
    }

    cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]);

    if (!sg) {
      this->SetError("Could not create or find source group");
      return false;
    }

    // handle regex
    if (parsedArguments.find(kRegexOptionName) != parsedArguments.end()) {
      const std::string& sgRegex = parsedArguments[kRegexOptionName].front();
      sg->SetGroupRegex(sgRegex.c_str());
    }

    // handle files
    const std::vector<std::string>& filesArguments =
      parsedArguments[kFilesOptionName];
    for (auto const& filesArg : filesArguments) {
      std::string src = filesArg;
      if (!cmSystemTools::FileIsFullPath(src)) {
        src = this->Makefile->GetCurrentSourceDirectory();
        src += "/";
        src += filesArg;
      }
      src = cmSystemTools::CollapseFullPath(src);
      sg->AddGroupFile(src);
    }
  }

  return true;
}

bool cmSourceGroupCommand::checkArgumentsPreconditions(
  const ParsedArguments& parsedArguments, std::string& errorMsg) const
{
  return checkSingleParameterArgumentPreconditions(
           kPrefixOptionName, parsedArguments, errorMsg) &&
    checkSingleParameterArgumentPreconditions(kTreeOptionName, parsedArguments,
                                              errorMsg) &&
    checkSingleParameterArgumentPreconditions(kRegexOptionName,
                                              parsedArguments, errorMsg);
}

bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments,
                                       std::string& errorMsg)
{
  const std::string root =
    cmSystemTools::CollapseFullPath(parsedArguments[kTreeOptionName].front());
  std::string prefix = parsedArguments[kPrefixOptionName].empty()
    ? ""
    : parsedArguments[kPrefixOptionName].front();

  const std::vector<std::string> filesVector =
    prepareFilesPathsForTree(parsedArguments[kFilesOptionName],
                             this->Makefile->GetCurrentSourceDirectory());

  if (!rootIsPrefix(root, filesVector, errorMsg)) {
    return false;
  }

  std::set<std::string> sourceGroupPaths =
    getSourceGroupFilesPaths(root, filesVector);

  return addFilesToItsSourceGroups(root, sourceGroupPaths, prefix,
                                   *(this->Makefile), errorMsg);
}

bool cmSourceGroupCommand::checkSingleParameterArgumentPreconditions(
  const std::string& argument, const ParsedArguments& parsedArguments,
  std::string& errorMsg) const
{
  ParsedArguments::const_iterator foundArgument =
    parsedArguments.find(argument);
  if (foundArgument != parsedArguments.end()) {
    const std::vector<std::string>& optionArguments = foundArgument->second;

    if (optionArguments.empty()) {
      errorMsg = argument + " argument given without an argument.";
      return false;
    }
    if (optionArguments.size() > 1) {
      errorMsg = "too many arguments passed to " + argument + ".";
      return false;
    }
  }

  return true;
}
