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

#include <algorithm>
#include <iterator>

#include <cm/string_view>
#include <cmext/algorithm>

#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSetPropertyCommand.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"

static bool RunCommandForScope(
  cmMakefile* mf, std::vector<std::string>::const_iterator file_begin,
  std::vector<std::string>::const_iterator file_end,
  std::vector<std::string>::const_iterator prop_begin,
  std::vector<std::string>::const_iterator prop_end, std::string& errors);

bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args,
                                       cmExecutionStatus& status)
{
  if (args.size() < 2) {
    status.SetError("called with incorrect number of arguments");
    return false;
  }

  // break the arguments into source file names and properties
  // old style allows for specifier before PROPERTIES keyword
  static const cm::string_view prop_names[] = {
    "ABSTRACT",       "GENERATED",  "WRAP_EXCLUDE", "COMPILE_FLAGS",
    "OBJECT_DEPENDS", "PROPERTIES", "DIRECTORY",    "TARGET_DIRECTORY"
  };

  auto isNotAPropertyKeyword =
    [](const std::vector<std::string>::const_iterator& arg_it) {
      return std::all_of(
        std::begin(prop_names), std::end(prop_names),
        [&arg_it](cm::string_view prop_name) { return *arg_it != prop_name; });
    };

  auto options_begin = std::find_first_of(
    args.begin(), args.end(), std::begin(prop_names), std::end(prop_names));
  auto options_it = options_begin;

  // Handle directory options.
  std::vector<std::string> source_file_directories;
  std::vector<std::string> source_file_target_directories;
  bool source_file_directory_option_enabled = false;
  bool source_file_target_option_enabled = false;
  std::vector<cmMakefile*> source_file_directory_makefiles;

  if (options_it != args.end() && *options_it == "DIRECTORY") {
    source_file_directory_option_enabled = true;
    ++options_it;
    while (options_it != args.end() && isNotAPropertyKeyword(options_it)) {
      source_file_directories.push_back(*options_it);
      ++options_it;
    }
  } else if (options_it != args.end() && *options_it == "TARGET_DIRECTORY") {
    source_file_target_option_enabled = true;
    ++options_it;
    while (options_it != args.end() && isNotAPropertyKeyword(options_it)) {
      source_file_target_directories.push_back(*options_it);
      ++options_it;
    }
  }
  const auto props_begin = options_it;

  bool file_scopes_handled =
    SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
      status, source_file_directory_option_enabled,
      source_file_target_option_enabled, source_file_directories,
      source_file_target_directories, source_file_directory_makefiles);
  if (!file_scopes_handled) {
    return false;
  }

  std::vector<std::string> files;
  bool source_file_paths_should_be_absolute =
    source_file_directory_option_enabled || source_file_target_option_enabled;
  SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded(
    status, files, args.begin(), options_begin,
    source_file_paths_should_be_absolute);

  // Now call the worker function for each directory scope represented by a
  // cmMakefile instance.
  std::string errors;
  for (const auto mf : source_file_directory_makefiles) {
    bool ret = RunCommandForScope(mf, files.begin(), files.end(), props_begin,
                                  args.end(), errors);
    if (!ret) {
      status.SetError(errors);
      return ret;
    }
  }

  return true;
}

static bool RunCommandForScope(
  cmMakefile* mf, std::vector<std::string>::const_iterator file_begin,
  std::vector<std::string>::const_iterator file_end,
  std::vector<std::string>::const_iterator prop_begin,
  std::vector<std::string>::const_iterator prop_end, std::string& errors)
{
  std::vector<std::string> propertyPairs;
  // build the property pairs
  for (auto j = prop_begin; j != prop_end; ++j) {
    // consume old style options
    if (*j == "ABSTRACT" || *j == "GENERATED" || *j == "WRAP_EXCLUDE") {
      propertyPairs.emplace_back(*j);
      propertyPairs.emplace_back("1");
    } else if (*j == "COMPILE_FLAGS") {
      propertyPairs.emplace_back("COMPILE_FLAGS");
      ++j;
      if (j == prop_end) {
        errors = "called with incorrect number of arguments "
                 "COMPILE_FLAGS with no flags";
        return false;
      }
      propertyPairs.push_back(*j);
    } else if (*j == "OBJECT_DEPENDS") {
      propertyPairs.emplace_back("OBJECT_DEPENDS");
      ++j;
      if (j == prop_end) {
        errors = "called with incorrect number of arguments "
                 "OBJECT_DEPENDS with no dependencies";
        return false;
      }
      propertyPairs.push_back(*j);
    } else if (*j == "PROPERTIES") {
      // PROPERTIES is followed by new style prop value pairs
      cmStringRange newStyleProps{ j + 1, prop_end };
      if (newStyleProps.size() % 2 != 0) {
        errors = "called with incorrect number of arguments.";
        return false;
      }
      // set newStyleProps as is.
      cm::append(propertyPairs, newStyleProps);
      // break out of the loop.
      break;
    } else {
      errors = "called with illegal arguments, maybe missing a "
               "PROPERTIES specifier?";
      return false;
    }
  }

  // loop over all the files
  for (const std::string& sfname : cmStringRange{ file_begin, file_end }) {
    // get the source file
    if (cmSourceFile* sf = mf->GetOrCreateSource(sfname)) {
      // loop through the props and set them
      for (auto k = propertyPairs.begin(); k != propertyPairs.end(); k += 2) {
        sf->SetProperty(*k, (k + 1)->c_str());
      }
    }
  }
  return true;
}
