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

#include <cm/optional>

#include "cmConfigureLog.h"
#include "cmCoreTryCompile.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmValue.h"
#include "cmake.h"

namespace {
#ifndef CMAKE_BOOTSTRAP
void WriteTryCompileEvent(cmConfigureLog& log, cmMakefile const& mf,
                          cmTryCompileResult const& compileResult)
{
  // Keep in sync with cmFileAPIConfigureLog's DumpEventKindNames.
  static std::vector<unsigned int> const LogVersionsWithTryCompileV1{ 1 };

  if (log.IsAnyLogVersionEnabled(LogVersionsWithTryCompileV1)) {
    log.BeginEvent("try_compile-v1", mf);
    cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult);
    log.EndEvent();
  }
}
#endif
}

bool cmTryCompileCommand(std::vector<std::string> const& args,
                         cmExecutionStatus& status)
{
  cmMakefile& mf = status.GetMakefile();

  if (args.size() < 3) {
    mf.IssueMessage(
      MessageType::FATAL_ERROR,
      "The try_compile() command requires at least 3 arguments.");
    return false;
  }

  if (mf.GetCMakeInstance()->GetWorkingMode() == cmake::FIND_PACKAGE_MODE) {
    mf.IssueMessage(
      MessageType::FATAL_ERROR,
      "The try_compile() command is not supported in --find-package mode.");
    return false;
  }

  cmStateEnums::TargetType targetType = cmStateEnums::EXECUTABLE;
  cmValue tt = mf.GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE");
  if (cmNonempty(tt)) {
    if (*tt == cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) {
      targetType = cmStateEnums::EXECUTABLE;
    } else if (*tt ==
               cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY)) {
      targetType = cmStateEnums::STATIC_LIBRARY;
    } else {
      mf.IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat("Invalid value '", *tt,
                 "' for CMAKE_TRY_COMPILE_TARGET_TYPE.  Only '",
                 cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE),
                 "' and '",
                 cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY),
                 "' are allowed."));
      return false;
    }
  }

  cmCoreTryCompile tc(&mf);
  cmCoreTryCompile::Arguments arguments =
    tc.ParseArgs(cmMakeRange(args), false);
  if (!arguments) {
    return true;
  }

  cm::optional<cmTryCompileResult> compileResult =
    tc.TryCompileCode(arguments, targetType);
#ifndef CMAKE_BOOTSTRAP
  if (compileResult && !arguments.NoLog) {
    if (cmConfigureLog* log = mf.GetCMakeInstance()->GetConfigureLog()) {
      WriteTryCompileEvent(*log, mf, *compileResult);
    }
  }
#endif

  // if They specified clean then we clean up what we can
  if (tc.SrcFileSignature) {
    if (!mf.GetCMakeInstance()->GetDebugTryCompile()) {
      tc.CleanupFiles(tc.BinaryDirectory);
    }
  }
  return true;
}
