// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/gn/c_tool.h"
#include "tools/gn/c_substitution_type.h"
#include "tools/gn/target.h"

const char* CTool::kCToolCc = "cc";
const char* CTool::kCToolCxx = "cxx";
const char* CTool::kCToolObjC = "objc";
const char* CTool::kCToolObjCxx = "objcxx";
const char* CTool::kCToolRc = "rc";
const char* CTool::kCToolAsm = "asm";
const char* CTool::kCToolAlink = "alink";
const char* CTool::kCToolSolink = "solink";
const char* CTool::kCToolSolinkModule = "solink_module";
const char* CTool::kCToolLink = "link";

CTool::CTool(const char* n)
    : Tool(n), depsformat_(DEPS_GCC), precompiled_header_type_(PCH_NONE) {
  CHECK(ValidateName(n));
}

CTool::~CTool() = default;

CTool* CTool::AsC() {
  return this;
}
const CTool* CTool::AsC() const {
  return this;
}

bool CTool::ValidateName(const char* name) const {
  return name == kCToolCc || name == kCToolCxx || name == kCToolObjC ||
         name == kCToolObjCxx || name == kCToolRc || name == kCToolAsm ||
         name == kCToolAlink || name == kCToolSolink ||
         name == kCToolSolinkModule || name == kCToolLink;
}

void CTool::SetComplete() {
  SetToolComplete();
  link_output_.FillRequiredTypes(&substitution_bits_);
  depend_output_.FillRequiredTypes(&substitution_bits_);
}

bool CTool::ValidateRuntimeOutputs(Err* err) {
  if (runtime_outputs().list().empty())
    return true;  // Empty is always OK.

  if (name_ != kCToolSolink && name_ != kCToolSolinkModule &&
      name_ != kCToolLink) {
    *err = Err(defined_from(), "This tool specifies runtime_outputs.",
               "This is only valid for linker tools (alink doesn't count).");
    return false;
  }

  for (const SubstitutionPattern& pattern : runtime_outputs().list()) {
    if (!IsPatternInOutputList(outputs(), pattern)) {
      *err = Err(defined_from(), "This tool's runtime_outputs is bad.",
                 "It must be a subset of the outputs. The bad one is:\n  " +
                     pattern.AsString());
      return false;
    }
  }
  return true;
}

// Validates either link_output or depend_output. To generalize to either, pass
// the associated pattern, and the variable name that should appear in error
// messages.
bool CTool::ValidateLinkAndDependOutput(const SubstitutionPattern& pattern,
                                        const char* variable_name,
                                        Err* err) {
  if (pattern.empty())
    return true;  // Empty is always OK.

  // It should only be specified for certain tool types.
  if (name_ != kCToolSolink && name_ != kCToolSolinkModule) {
    *err = Err(defined_from(),
               "This tool specifies a " + std::string(variable_name) + ".",
               "This is only valid for solink and solink_module tools.");
    return false;
  }

  if (!IsPatternInOutputList(outputs(), pattern)) {
    *err = Err(defined_from(), "This tool's link_output is bad.",
               "It must match one of the outputs.");
    return false;
  }

  return true;
}

bool CTool::ReadPrecompiledHeaderType(Scope* scope, Err* err) {
  const Value* value = scope->GetValue("precompiled_header_type", true);
  if (!value)
    return true;  // Not present is fine.
  if (!value->VerifyTypeIs(Value::STRING, err))
    return false;

  if (value->string_value().empty())
    return true;  // Accept empty string, do nothing (default is "no PCH").

  if (value->string_value() == "gcc") {
    set_precompiled_header_type(PCH_GCC);
    return true;
  } else if (value->string_value() == "msvc") {
    set_precompiled_header_type(PCH_MSVC);
    return true;
  }
  *err = Err(*value, "Invalid precompiled_header_type",
             "Must either be empty, \"gcc\", or \"msvc\".");
  return false;
}

bool CTool::ReadDepsFormat(Scope* scope, Err* err) {
  const Value* value = scope->GetValue("depsformat", true);
  if (!value)
    return true;  // Not present is fine.
  if (!value->VerifyTypeIs(Value::STRING, err))
    return false;

  if (value->string_value() == "gcc") {
    set_depsformat(DEPS_GCC);
  } else if (value->string_value() == "msvc") {
    set_depsformat(DEPS_MSVC);
  } else {
    *err = Err(*value, "Deps format must be \"gcc\" or \"msvc\".");
    return false;
  }
  return true;
}

bool CTool::ReadOutputsPatternList(Scope* scope,
                                   const char* var,
                                   SubstitutionList* field,
                                   Err* err) {
  DCHECK(!complete_);
  const Value* value = scope->GetValue(var, true);
  if (!value)
    return true;  // Not present is fine.
  if (!value->VerifyTypeIs(Value::LIST, err))
    return false;

  SubstitutionList list;
  if (!list.Parse(*value, err))
    return false;

  // Validate the right kinds of patterns are used.
  if (list.list().empty()) {
    *err = Err(defined_from(), "\"outputs\" must be specified for this tool.");
    return false;
  }

  for (const auto& cur_type : list.required_types()) {
    if (!ValidateOutputSubstitution(cur_type)) {
      *err = Err(*value, "Pattern not valid here.",
                 "You used the pattern " + std::string(cur_type->name) +
                     " which is not valid\nfor this variable.");
      return false;
    }
  }

  *field = std::move(list);
  return true;
}

bool CTool::InitTool(Scope* scope, Toolchain* toolchain, Err* err) {
  // Initialize default vars.
  if (!Tool::InitTool(scope, toolchain, err)) {
    return false;
  }

  // All C tools should have outputs.
  if (!ReadOutputsPatternList(scope, "outputs", &outputs_, err)) {
    return false;
  }

  if (!ReadDepsFormat(scope, err) || !ReadPrecompiledHeaderType(scope, err) ||
      !ReadString(scope, "lib_switch", &lib_switch_, err) ||
      !ReadString(scope, "lib_dir_switch", &lib_dir_switch_, err) ||
      !ReadPattern(scope, "link_output", &link_output_, err) ||
      !ReadPattern(scope, "depend_output", &depend_output_, err)) {
    return false;
  }

  // Validate link_output and depend_output.
  if (!ValidateLinkAndDependOutput(link_output(), "link_output", err)) {
    return false;
  }
  if (!ValidateLinkAndDependOutput(depend_output(), "depend_output", err)) {
    return false;
  }
  if ((!link_output().empty() && depend_output().empty()) ||
      (link_output().empty() && !depend_output().empty())) {
    *err = Err(defined_from(),
               "Both link_output and depend_output should either "
               "be specified or they should both be empty.");
    return false;
  }

  if (!ValidateRuntimeOutputs(err)) {
    return false;
  }
  return true;
}

bool CTool::ValidateSubstitution(const Substitution* sub_type) const {
  if (name_ == kCToolCc || name_ == kCToolCxx || name_ == kCToolObjC ||
      name_ == kCToolObjCxx || name_ == kCToolRc || name_ == kCToolAsm)
    return IsValidCompilerSubstitution(sub_type);
  else if (name_ == kCToolAlink)
    return IsValidALinkSubstitution(sub_type);
  else if (name_ == kCToolSolink || name_ == kCToolSolinkModule ||
           name_ == kCToolLink)
    return IsValidLinkerSubstitution(sub_type);
  NOTREACHED();
  return false;
}

bool CTool::ValidateOutputSubstitution(const Substitution* sub_type) const {
  if (name_ == kCToolCc || name_ == kCToolCxx || name_ == kCToolObjC ||
      name_ == kCToolObjCxx || name_ == kCToolRc || name_ == kCToolAsm)
    return IsValidCompilerOutputsSubstitution(sub_type);
  // ALink uses the standard output file patterns as other linker tools.
  else if (name_ == kCToolAlink || name_ == kCToolSolink ||
           name_ == kCToolSolinkModule || name_ == kCToolLink)
    return IsValidLinkerOutputsSubstitution(sub_type);
  NOTREACHED();
  return false;
}
