// Copyright (c) 2013 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/config_values_generator.h"

#include "base/strings/string_util.h"
#include "tools/gn/config_values.h"
#include "tools/gn/scope.h"
#include "tools/gn/settings.h"
#include "tools/gn/value.h"
#include "tools/gn/value_extractors.h"
#include "tools/gn/variables.h"

namespace {

void GetStringList(Scope* scope,
                   const char* var_name,
                   ConfigValues* config_values,
                   std::vector<std::string>& (ConfigValues::*accessor)(),
                   Err* err) {
  const Value* value = scope->GetValue(var_name, true);
  if (!value)
    return;  // No value, empty input and succeed.

  ExtractListOfStringValues(*value, &(config_values->*accessor)(), err);
}

void GetDirList(Scope* scope,
                const char* var_name,
                ConfigValues* config_values,
                const SourceDir input_dir,
                std::vector<SourceDir>& (ConfigValues::*accessor)(),
                Err* err) {
  const Value* value = scope->GetValue(var_name, true);
  if (!value)
    return;  // No value, empty input and succeed.

  std::vector<SourceDir> result;
  ExtractListOfRelativeDirs(scope->settings()->build_settings(), *value,
                            input_dir, &result, err);
  (config_values->*accessor)().swap(result);
}

}  // namespace

ConfigValuesGenerator::ConfigValuesGenerator(ConfigValues* dest_values,
                                             Scope* scope,
                                             const SourceDir& input_dir,
                                             Err* err)
    : config_values_(dest_values),
      scope_(scope),
      input_dir_(input_dir),
      err_(err) {}

ConfigValuesGenerator::~ConfigValuesGenerator() = default;

void ConfigValuesGenerator::Run() {
#define FILL_STRING_CONFIG_VALUE(name) \
  GetStringList(scope_, #name, config_values_, &ConfigValues::name, err_);
#define FILL_DIR_CONFIG_VALUE(name)                                          \
  GetDirList(scope_, #name, config_values_, input_dir_, &ConfigValues::name, \
             err_);

  FILL_STRING_CONFIG_VALUE(arflags)
  FILL_STRING_CONFIG_VALUE(asmflags)
  FILL_STRING_CONFIG_VALUE(cflags)
  FILL_STRING_CONFIG_VALUE(cflags_c)
  FILL_STRING_CONFIG_VALUE(cflags_cc)
  FILL_STRING_CONFIG_VALUE(cflags_objc)
  FILL_STRING_CONFIG_VALUE(cflags_objcc)
  FILL_STRING_CONFIG_VALUE(defines)
  FILL_DIR_CONFIG_VALUE(include_dirs)
  FILL_STRING_CONFIG_VALUE(ldflags)
  FILL_DIR_CONFIG_VALUE(lib_dirs)
  FILL_STRING_CONFIG_VALUE(rustflags)
  FILL_STRING_CONFIG_VALUE(rustenv)

#undef FILL_STRING_CONFIG_VALUE
#undef FILL_DIR_CONFIG_VALUE

  // Inputs
  const Value* inputs_value = scope_->GetValue(variables::kInputs, true);
  if (inputs_value) {
    ExtractListOfRelativeFiles(scope_->settings()->build_settings(),
                               *inputs_value, input_dir_,
                               &config_values_->inputs(), err_);
  }

  // Libs
  const Value* libs_value = scope_->GetValue("libs", true);
  if (libs_value) {
    ExtractListOfLibs(scope_->settings()->build_settings(), *libs_value,
                      input_dir_, &config_values_->libs(), err_);
  }

  // Precompiled headers.
  const Value* precompiled_header_value =
      scope_->GetValue(variables::kPrecompiledHeader, true);
  if (precompiled_header_value) {
    if (!precompiled_header_value->VerifyTypeIs(Value::STRING, err_))
      return;

    // Check for common errors. This is a string and not a file.
    const std::string& pch_string = precompiled_header_value->string_value();
    if (base::StartsWith(pch_string, "//", base::CompareCase::SENSITIVE)) {
      *err_ = Err(
          *precompiled_header_value, "This precompiled_header value is wrong.",
          "You need to specify a string that the compiler will match against\n"
          "the #include lines rather than a GN-style file name.\n");
      return;
    }
    config_values_->set_precompiled_header(pch_string);
  }

  const Value* precompiled_source_value =
      scope_->GetValue(variables::kPrecompiledSource, true);
  if (precompiled_source_value) {
    config_values_->set_precompiled_source(input_dir_.ResolveRelativeFile(
        *precompiled_source_value, err_,
        scope_->settings()->build_settings()->root_path_utf8()));
    if (err_->has_error())
      return;
  }
}
