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

#include <iomanip>
#include <sstream>
#include <utility>

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

#include "cmsys/String.h"

#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmXCodeObject.h"
#include "cmXMLWriter.h"

class cmLocalGenerator;

cmXCodeScheme::cmXCodeScheme(cmLocalGenerator* lg, cmXCodeObject* xcObj,
                             TestObjects tests,
                             std::vector<std::string> const& configList,
                             unsigned int xcVersion)
  : LocalGenerator(lg)
  , Target(xcObj)
  , Tests(std::move(tests))
  , TargetName(xcObj->GetTarget()->GetName())
  , ConfigList(configList)
  , XcodeVersion(xcVersion)
{
}

void cmXCodeScheme::WriteXCodeSharedScheme(std::string const& xcProjDir,
                                           std::string const& container)
{
  // Create shared scheme sub-directory tree
  //
  std::string xcodeSchemeDir = cmStrCat(xcProjDir, "/xcshareddata/xcschemes");
  cmSystemTools::MakeDirectory(xcodeSchemeDir);

  std::string xcodeSchemeFile =
    cmStrCat(xcodeSchemeDir, '/', this->TargetName, ".xcscheme");

  cmGeneratedFileStream fout(xcodeSchemeFile);
  fout.SetCopyIfDifferent(true);
  if (!fout) {
    return;
  }

  WriteXCodeXCScheme(fout, container);
}

void cmXCodeScheme::WriteXCodeXCScheme(std::ostream& fout,
                                       std::string const& container)
{
  cmXMLWriter xout(fout);
  xout.SetIndentationElement(std::string(3, ' '));
  xout.StartDocument();

  xout.StartElement("Scheme");
  xout.BreakAttributes();
  xout.Attribute("LastUpgradeVersion", WriteVersionString());
  xout.Attribute("version", "1.3");

  cmValue propDftCfg =
    Target->GetTarget()->GetProperty("XCODE_SCHEME_LAUNCH_CONFIGURATION");
  std::string launchConfiguration =
    !propDftCfg.IsEmpty() ? *propDftCfg : "Debug";

  cmValue propTstCfg =
    Target->GetTarget()->GetProperty("XCODE_SCHEME_TEST_CONFIGURATION");
  std::string testConfiguration =
    !propTstCfg.IsEmpty() ? *propTstCfg : "Debug";

  WriteBuildAction(xout, container);
  WriteTestAction(xout, FindConfiguration(testConfiguration), container);
  WriteLaunchAction(xout, FindConfiguration(launchConfiguration), container);
  WriteProfileAction(xout, FindConfiguration("Release"), container);
  WriteAnalyzeAction(xout, FindConfiguration("Debug"));
  WriteArchiveAction(xout, FindConfiguration("Release"));

  xout.EndElement();
}

void cmXCodeScheme::WriteBuildAction(cmXMLWriter& xout,
                                     std::string const& container)
{
  xout.StartElement("BuildAction");
  xout.BreakAttributes();
  xout.Attribute("parallelizeBuildables", "YES");
  xout.Attribute("buildImplicitDependencies", "YES");

  xout.StartElement("BuildActionEntries");
  xout.StartElement("BuildActionEntry");
  xout.BreakAttributes();
  xout.Attribute("buildForTesting", "YES");
  xout.Attribute("buildForRunning", "YES");
  xout.Attribute("buildForProfiling", "YES");
  xout.Attribute("buildForArchiving", "YES");
  xout.Attribute("buildForAnalyzing", "YES");

  WriteBuildableReference(xout, this->Target, container);

  xout.EndElement(); // BuildActionEntry
  xout.EndElement(); // BuildActionEntries
  xout.EndElement(); // BuildAction
}

void cmXCodeScheme::WriteTestAction(cmXMLWriter& xout,
                                    std::string const& configuration,
                                    std::string const& container)
{
  xout.StartElement("TestAction");
  xout.BreakAttributes();
  xout.Attribute("buildConfiguration", configuration);
  xout.Attribute("selectedDebuggerIdentifier",
                 "Xcode.DebuggerFoundation.Debugger.LLDB");
  xout.Attribute("selectedLauncherIdentifier",
                 "Xcode.DebuggerFoundation.Launcher.LLDB");
  xout.Attribute("shouldUseLaunchSchemeArgsEnv", "YES");
  WriteCustomLLDBInitFile(xout, configuration);

  xout.StartElement("Testables");
  for (auto const* test : this->Tests) {
    xout.StartElement("TestableReference");
    xout.BreakAttributes();
    xout.Attribute("skipped", "NO");
    WriteBuildableReference(xout, test, container);
    xout.EndElement(); // TestableReference
  }
  xout.EndElement();

  if (IsTestable()) {
    xout.StartElement("MacroExpansion");
    WriteBuildableReference(xout, this->Target, container);
    xout.EndElement(); // MacroExpansion
  }

  xout.StartElement("AdditionalOptions");
  xout.EndElement();

  xout.EndElement(); // TestAction
}

void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
                                      std::string const& configuration,
                                      std::string const& container)
{
  xout.StartElement("LaunchAction");
  xout.BreakAttributes();
  xout.Attribute("buildConfiguration", configuration);
  xout.Attribute("selectedDebuggerIdentifier",
                 "Xcode.DebuggerFoundation.Debugger.LLDB");
  xout.Attribute("selectedLauncherIdentifier",
                 "Xcode.DebuggerFoundation.Launcher.LLDB");
  {
    cmValue launchMode =
      this->Target->GetTarget()->GetProperty("XCODE_SCHEME_LAUNCH_MODE");
    std::string value = "0"; // == 'AUTO'
    if (launchMode && *launchMode == "WAIT"_s) {
      value = "1";
    }
    xout.Attribute("launchStyle", value);
  }
  WriteCustomWorkingDirectory(xout, configuration);
  WriteCustomLLDBInitFile(xout, configuration);

  xout.Attribute("ignoresPersistentStateOnLaunch", "NO");
  WriteLaunchActionBooleanAttribute(xout, "debugDocumentVersioning",
                                    "XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING",
                                    true);
  xout.Attribute("debugServiceExtension", "internal");
  xout.Attribute("allowLocationSimulation", "YES");
  if (cmValue gpuFrameCaptureMode = this->Target->GetTarget()->GetProperty(
        "XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE")) {
    std::string value = *gpuFrameCaptureMode;
    if (cmsysString_strcasecmp(value.c_str(), "Metal") == 0) {
      value = "1";
    } else if (cmsysString_strcasecmp(value.c_str(), "Disabled") == 0) {
      value = "3";
    }
    xout.Attribute("enableGPUFrameCaptureMode", value);
  }

  // Diagnostics tab begin

  bool useAddressSanitizer = WriteLaunchActionAttribute(
    xout, "enableAddressSanitizer",
    "XCODE_SCHEME_ADDRESS_SANITIZER"); // not allowed with
                                       // enableThreadSanitizer=YES
  WriteLaunchActionAttribute(
    xout, "enableASanStackUseAfterReturn",
    "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN");

  bool useThreadSanitizer = false;
  if (!useAddressSanitizer) {
    useThreadSanitizer = WriteLaunchActionAttribute(
      xout, "enableThreadSanitizer",
      "XCODE_SCHEME_THREAD_SANITIZER"); // not allowed with
                                        // enableAddressSanitizer=YES
  }

  WriteLaunchActionAttribute(xout, "stopOnEveryThreadSanitizerIssue",
                             "XCODE_SCHEME_THREAD_SANITIZER_STOP");

  WriteLaunchActionAttribute(xout, "enableUBSanitizer",
                             "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER");

  if (cmValue value = this->Target->GetTarget()->GetProperty(
        "XCODE_SCHEME_ENABLE_GPU_API_VALIDATION")) {
    if (value.IsOff()) {
      xout.Attribute("enableGPUValidationMode",
                     "1"); // unset means YES, "1" means NO
    }
  }

  if (cmValue value = this->Target->GetTarget()->GetProperty(
        "XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION")) {
    if (value.IsOn()) {
      xout.Attribute("enableGPUShaderValidationMode",
                     "2"); // unset means NO, "2" means YES
    }
  }

  WriteLaunchActionAttribute(
    xout, "stopOnEveryUBSanitizerIssue",
    "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP");

  WriteLaunchActionAttribute(
    xout, "disableMainThreadChecker",
    "XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER"); // negative enabled!
  WriteLaunchActionAttribute(xout, "stopOnEveryMainThreadCheckerIssue",
                             "XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP");

  if (this->Target->GetTarget()->GetPropertyAsBool(
        "XCODE_SCHEME_DEBUG_AS_ROOT")) {
    xout.Attribute("debugAsWhichUser", "root");
  }

  // Diagnostics tab end

  if (IsExecutable(this->Target)) {
    WriteBuildableProductRunnable(xout, this->Target, container);
  } else {
    xout.StartElement("MacroExpansion");
    WriteBuildableReference(xout, this->Target, container);
    xout.EndElement();
  }

  // Info tab begin

  if (cmValue exe =
        this->Target->GetTarget()->GetProperty("XCODE_SCHEME_EXECUTABLE")) {

    xout.StartElement("PathRunnable");
    xout.BreakAttributes();

    xout.Attribute("runnableDebuggingMode", "0");
    xout.Attribute("FilePath", *exe);

    xout.EndElement(); // PathRunnable
  }

  // Info tab end

  // Arguments tab begin

  if (cmValue argList =
        this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) {
    cmList arguments{ *argList };
    if (!arguments.empty()) {
      xout.StartElement("CommandLineArguments");

      for (auto const& argument : arguments) {
        xout.StartElement("CommandLineArgument");
        xout.BreakAttributes();

        xout.Attribute("argument", argument);
        xout.Attribute("isEnabled", "YES");

        xout.EndElement(); // CommandLineArgument
      }

      xout.EndElement(); // CommandLineArguments
    }
  }

  if (cmValue envList =
        this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) {
    cmList envs{ *envList };
    if (!envs.empty()) {
      xout.StartElement("EnvironmentVariables");

      for (auto env : envs) {

        xout.StartElement("EnvironmentVariable");
        xout.BreakAttributes();

        std::string envValue;
        auto const p = env.find_first_of('=');
        if (p != std::string::npos) {
          envValue = env.substr(p + 1);
          env.resize(p);
        }

        xout.Attribute("key", env);
        xout.Attribute("value", envValue);
        xout.Attribute("isEnabled", "YES");

        xout.EndElement(); // EnvironmentVariable
      }

      xout.EndElement(); // EnvironmentVariables
    }
  }

  // Arguments tab end

  xout.StartElement("AdditionalOptions");

  if (!useThreadSanitizer) {
    WriteLaunchActionAdditionalOption(xout, "MallocScribble", "",
                                      "XCODE_SCHEME_MALLOC_SCRIBBLE");
  }

  if (!useThreadSanitizer && !useAddressSanitizer) {
    WriteLaunchActionAdditionalOption(xout, "MallocGuardEdges", "",
                                      "XCODE_SCHEME_MALLOC_GUARD_EDGES");
  }

  if (!useThreadSanitizer && !useAddressSanitizer) {
    WriteLaunchActionAdditionalOption(xout, "DYLD_INSERT_LIBRARIES",
                                      "/usr/lib/libgmalloc.dylib",
                                      "XCODE_SCHEME_GUARD_MALLOC");
  }

  WriteLaunchActionAdditionalOption(xout, "NSZombieEnabled", "YES",
                                    "XCODE_SCHEME_ZOMBIE_OBJECTS");

  if (!useThreadSanitizer && !useAddressSanitizer) {
    WriteLaunchActionAdditionalOption(xout, "MallocStackLogging", "",
                                      "XCODE_SCHEME_MALLOC_STACK");
  }

  WriteLaunchActionAdditionalOption(xout, "DYLD_PRINT_APIS", "",
                                    "XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE");

  WriteLaunchActionAdditionalOption(xout, "DYLD_PRINT_LIBRARIES", "",
                                    "XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS");

  xout.EndElement();

  xout.EndElement(); // LaunchAction
}

bool cmXCodeScheme::WriteLaunchActionAttribute(cmXMLWriter& xout,
                                               std::string const& attrName,
                                               std::string const& varName)
{
  if (Target->GetTarget()->GetPropertyAsBool(varName)) {
    xout.Attribute(attrName.c_str(), "YES");
    return true;
  }
  return false;
}

bool cmXCodeScheme::WriteLaunchActionBooleanAttribute(
  cmXMLWriter& xout, std::string const& attrName, std::string const& varName,
  bool defaultValue)
{
  cmValue property = Target->GetTarget()->GetProperty(varName);
  bool isOn = (!property && defaultValue) || property.IsOn();

  if (isOn) {
    xout.Attribute(attrName.c_str(), "YES");
  } else {
    xout.Attribute(attrName.c_str(), "NO");
  }
  return isOn;
}

bool cmXCodeScheme::WriteLaunchActionAdditionalOption(
  cmXMLWriter& xout, std::string const& key, std::string const& value,
  std::string const& varName)
{
  if (Target->GetTarget()->GetPropertyAsBool(varName)) {
    xout.StartElement("AdditionalOption");
    xout.BreakAttributes();

    xout.Attribute("key", key);
    xout.Attribute("value", value);
    xout.Attribute("isEnabled", "YES");

    xout.EndElement(); // AdditionalOption

    return true;
  }
  return false;
}

void cmXCodeScheme::WriteProfileAction(cmXMLWriter& xout,
                                       std::string const& configuration,
                                       std::string const& container)
{
  xout.StartElement("ProfileAction");
  xout.BreakAttributes();
  xout.Attribute("buildConfiguration", configuration);
  xout.Attribute("shouldUseLaunchSchemeArgsEnv", "YES");
  xout.Attribute("savedToolIdentifier", "");
  WriteCustomWorkingDirectory(xout, configuration);
  WriteLaunchActionBooleanAttribute(xout, "debugDocumentVersioning",
                                    "XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING",
                                    true);

  if (IsExecutable(this->Target)) {
    WriteBuildableProductRunnable(xout, this->Target, container);
  }

  xout.EndElement();
}

void cmXCodeScheme::WriteAnalyzeAction(cmXMLWriter& xout,
                                       std::string const& configuration)
{
  xout.StartElement("AnalyzeAction");
  xout.BreakAttributes();
  xout.Attribute("buildConfiguration", configuration);
  xout.EndElement();
}

void cmXCodeScheme::WriteArchiveAction(cmXMLWriter& xout,
                                       std::string const& configuration)
{
  xout.StartElement("ArchiveAction");
  xout.BreakAttributes();
  xout.Attribute("buildConfiguration", configuration);
  xout.Attribute("revealArchiveInOrganizer", "YES");
  xout.EndElement();
}

void cmXCodeScheme::WriteBuildableProductRunnable(cmXMLWriter& xout,
                                                  cmXCodeObject const* xcObj,
                                                  std::string const& container)
{
  xout.StartElement("BuildableProductRunnable");
  xout.BreakAttributes();
  xout.Attribute("runnableDebuggingMode", "0");
  WriteBuildableReference(xout, xcObj, container);
  xout.EndElement();
}

void cmXCodeScheme::WriteBuildableReference(cmXMLWriter& xout,
                                            cmXCodeObject const* xcObj,
                                            std::string const& container)
{
  xout.StartElement("BuildableReference");
  xout.BreakAttributes();
  xout.Attribute("BuildableIdentifier", "primary");
  xout.Attribute("BlueprintIdentifier", xcObj->GetId());
  std::string const noConfig; // FIXME: What config to use here?
  xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName(noConfig));
  xout.Attribute("BlueprintName", xcObj->GetTarget()->GetName());
  xout.Attribute("ReferencedContainer", cmStrCat("container:", container));
  xout.EndElement();
}

void cmXCodeScheme::WriteCustomWorkingDirectory(
  cmXMLWriter& xout, std::string const& configuration)
{
  cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();

  cmValue propertyValue =
    gg->GetDebuggerWorkingDirectory(this->Target->GetTarget());
  if (!propertyValue) {
    xout.Attribute("useCustomWorkingDirectory", "NO");
  } else {
    xout.Attribute("useCustomWorkingDirectory", "YES");

    auto customWorkingDirectory = cmGeneratorExpression::Evaluate(
      *propertyValue, this->LocalGenerator, configuration);
    xout.Attribute("customWorkingDirectory", customWorkingDirectory);
  }
}

void cmXCodeScheme::WriteCustomLLDBInitFile(cmXMLWriter& xout,
                                            std::string const& configuration)
{
  std::string const& propertyValue =
    this->Target->GetTarget()->GetSafeProperty("XCODE_SCHEME_LLDB_INIT_FILE");
  if (!propertyValue.empty()) {
    auto customLLDBInitFile = cmGeneratorExpression::Evaluate(
      propertyValue, this->LocalGenerator, configuration);
    xout.Attribute("customLLDBInitFile", customLLDBInitFile);
  }
}

std::string cmXCodeScheme::WriteVersionString()
{
  std::ostringstream v;
  v << std::setfill('0') << std::setw(4) << this->XcodeVersion * 10;
  return v.str();
}

std::string cmXCodeScheme::FindConfiguration(std::string const& name)
{
  // Try to find the desired configuration by name,
  // and if it's not found return first from the list
  //
  if (!cm::contains(this->ConfigList, name) && !this->ConfigList.empty()) {
    return this->ConfigList[0];
  }

  return name;
}

bool cmXCodeScheme::IsTestable() const
{
  return !this->Tests.empty() || IsExecutable(this->Target);
}

bool cmXCodeScheme::IsExecutable(cmXCodeObject const* target)
{
  cmGeneratorTarget* gt = target->GetTarget();
  if (!gt) {
    cmSystemTools::Error("Error no target on xobject\n");
    return false;
  }

  return gt->GetType() == cmStateEnums::EXECUTABLE;
}
