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

#include <cstring>

#include <cm/string_view>

#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

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

  cmMakefile& mf = status.GetMakefile();
  // store the binpath
  std::string const& srcArg = args.front();
  std::string binArg;

  bool excludeFromAll = false;
  bool system = false;

  // process the rest of the arguments looking for optional args
  for (std::string const& arg : cmMakeRange(args).advance(1)) {
    if (arg == "EXCLUDE_FROM_ALL") {
      excludeFromAll = true;
      continue;
    }
    if (arg == "SYSTEM") {
      system = true;
      continue;
    }
    if (binArg.empty()) {
      binArg = arg;
    } else {
      status.SetError("called with incorrect number of arguments");
      return false;
    }
  }
  // "SYSTEM" directory property should also affects targets in nested
  // subdirectories.
  if (mf.GetPropertyAsBool("SYSTEM")) {
    system = true;
  }

  // Compute the full path to the specified source directory.
  // Interpret a relative path with respect to the current source directory.
  std::string srcPath;
  if (cmSystemTools::FileIsFullPath(srcArg)) {
    srcPath = srcArg;
  } else {
    srcPath = cmStrCat(mf.GetCurrentSourceDirectory(), '/', srcArg);
  }
  if (!cmSystemTools::FileIsDirectory(srcPath)) {
    std::string error = cmStrCat("given source \"", srcArg,
                                 "\" which is not an existing directory.");
    status.SetError(error);
    return false;
  }
  srcPath =
    cmSystemTools::CollapseFullPath(srcPath, mf.GetHomeOutputDirectory());

  // Compute the full path to the binary directory.
  std::string binPath;
  if (binArg.empty()) {
    // No binary directory was specified.  If the source directory is
    // not a subdirectory of the current directory then it is an
    // error.
    if (!cmSystemTools::IsSubDirectory(srcPath,
                                       mf.GetCurrentSourceDirectory())) {
      status.SetError(
        cmStrCat("not given a binary directory but the given source "
                 "directory \"",
                 srcPath, "\" is not a subdirectory of \"",
                 mf.GetCurrentSourceDirectory(),
                 "\".  When specifying an "
                 "out-of-tree source a binary directory must be explicitly "
                 "specified."));
      return false;
    }

    // Remove the CurrentDirectory from the srcPath and replace it
    // with the CurrentOutputDirectory.
    std::string const& src = mf.GetCurrentSourceDirectory();
    std::string const& bin = mf.GetCurrentBinaryDirectory();
    size_t srcLen = src.length();
    size_t binLen = bin.length();
    if (srcLen > 0 && src.back() == '/') {
      --srcLen;
    }
    if (binLen > 0 && bin.back() == '/') {
      --binLen;
    }
    binPath = cmStrCat(cm::string_view(bin).substr(0, binLen),
                       cm::string_view(srcPath).substr(srcLen));
  } else {
    // Use the binary directory specified.
    // Interpret a relative path with respect to the current binary directory.
    if (cmSystemTools::FileIsFullPath(binArg)) {
      binPath = binArg;
    } else {
      binPath = cmStrCat(mf.GetCurrentBinaryDirectory(), '/', binArg);
    }
  }
  binPath = cmSystemTools::CollapseFullPath(binPath);

  // Add the subdirectory using the computed full paths.
  mf.AddSubDirectory(srcPath, binPath, excludeFromAll, true, system);

  return true;
}
