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

#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#if defined(CMake_USE_MACH_PARSER)
#  include "cmMachO.h"
#endif

#include <cmext/string_view>

bool HandleReadMachoCommand(std::vector<std::string> const& args,
                            cmExecutionStatus& status)
{
  if (args.size() < 4) {
    status.SetError("READ_MACHO must be called with at least three additional "
                    "arguments.");
    return false;
  }

  std::string const& fileNameArg = args[1];

  struct Arguments
  {
    std::string Architectures;
    std::string Error;
  };

  static auto const parser =
    cmArgumentParser<Arguments>{}
      .Bind("ARCHITECTURES"_s, &Arguments::Architectures)
      .Bind("CAPTURE_ERROR"_s, &Arguments::Error);
  Arguments const arguments = parser.Parse(cmMakeRange(args).advance(2),
                                           /*unparsedArguments=*/nullptr);

  if (!arguments.Architectures.empty()) {
    // always return something  sensible for ARCHITECTURES
    status.GetMakefile().AddDefinition(arguments.Architectures, "unknown"_s);
  }
  if (!cmSystemTools::FileExists(fileNameArg, true)) {
    if (arguments.Error.empty()) {
      status.SetError(cmStrCat("READ_MACHO given FILE \"", fileNameArg,
                               "\" that does not exist."));
      return false;
    }
    status.GetMakefile().AddDefinition(
      arguments.Error, cmStrCat(fileNameArg, " does not exist"));
    return true;
  }

#if defined(CMake_USE_MACH_PARSER)
  cmMachO macho(fileNameArg.c_str());
  if (!macho) {
    if (arguments.Error.empty()) {
      status.SetError(cmStrCat("READ_MACHO given FILE:\n  ", fileNameArg,
                               "\nthat is not a valid Macho-O file."));
      return false;
    }
    status.GetMakefile().AddDefinition(
      arguments.Error, cmStrCat(fileNameArg, " is not a valid Macho-O file"));
    return true;
  } else if (!macho.GetErrorMessage().empty()) {
    if (arguments.Error.empty()) {
      status.SetError(cmStrCat(
        "READ_MACHO given FILE:\n  ", fileNameArg,
        "\nthat is not a supported Macho-O file: ", macho.GetErrorMessage()));
      return false;
    }
    status.GetMakefile().AddDefinition(
      arguments.Error,
      cmStrCat(fileNameArg,
               " is not a supported Macho-O file: ", macho.GetErrorMessage()));
    return true;
  }

  std::string output;

  if (!arguments.Architectures.empty()) {
    auto archs = macho.GetArchitectures();
    output = cmJoin(archs, ";");

    // Save the output in a makefile variable.
    status.GetMakefile().AddDefinition(arguments.Architectures, output);
  }
#else
  if (arguments.Error.empty()) {
    status.SetError("READ_MACHO support not available on this platform.");
    return false;
  }
  status.GetMakefile().AddDefinition(
    arguments.Error, "READ_MACHO support not available on this platform.");
#endif // CMake_USE_MACH_PARSER
  return true;
}
