// 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)

#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;
  }
}
