// Copyright 2018 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/generated_file_target_generator.h"

#include "tools/gn/err.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/scope.h"
#include "tools/gn/target.h"
#include "tools/gn/variables.h"

GeneratedFileTargetGenerator::GeneratedFileTargetGenerator(
    Target* target,
    Scope* scope,
    const FunctionCallNode* function_call,
    Target::OutputType type,
    Err* err)
    : TargetGenerator(target, scope, function_call, err), output_type_(type) {}

GeneratedFileTargetGenerator::~GeneratedFileTargetGenerator() = default;

void GeneratedFileTargetGenerator::DoRun() {
  target_->set_output_type(output_type_);

  if (!FillOutputs(false))
    return;
  if (target_->action_values().outputs().list().size() != 1) {
    *err_ = Err(
        function_call_, "generated_file target must have exactly one output.",
        "You must specify exactly one value in the \"outputs\" array for the "
        "destination of the write\n(see \"gn help generated_file\").");
    return;
  }

  if (!FillContents())
    return;
  if (!FillDataKeys())
    return;

  // One of data and data_keys should be defined.
  if (!contents_defined_ && !data_keys_defined_) {
    *err_ = Err(
        function_call_, "Either contents or data_keys should be set.",
        "The generated_file target requires either the \"contents\" variable "
        "or the \"data_keys\" variable be set. See \"gn help "
        "generated_file\".");
    return;
  }

  if (!FillRebase())
    return;
  if (!FillWalkKeys())
    return;

  if (!FillOutputConversion())
    return;
}

bool GeneratedFileTargetGenerator::FillContents() {
  const Value* value = scope_->GetValue(variables::kWriteValueContents, true);
  if (!value)
    return true;
  target_->set_contents(*value);
  contents_defined_ = true;
  return true;
}

bool GeneratedFileTargetGenerator::IsMetadataCollectionTarget(
    const base::StringPiece& variable,
    const ParseNode* origin) {
  if (contents_defined_) {
    *err_ =
        Err(origin, variable.as_string() + " won't be used.",
            "\"contents\" is defined on this target, and so setting " +
                variable.as_string() +
                " will have no effect as no metdata collection will occur.");
    return false;
  }
  return true;
}

bool GeneratedFileTargetGenerator::FillOutputConversion() {
  const Value* value =
      scope_->GetValue(variables::kWriteOutputConversion, true);
  if (!value) {
    target_->set_output_conversion(Value(function_call_, ""));
    return true;
  }
  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;

  // Otherwise, the value itself will be checked when the conversion is done.
  target_->set_output_conversion(*value);
  return true;
}

bool GeneratedFileTargetGenerator::FillRebase() {
  const Value* value = scope_->GetValue(variables::kRebase, true);
  if (!value)
    return true;
  if (!IsMetadataCollectionTarget(variables::kRebase, value->origin()))
    return false;
  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;

  if (value->string_value().empty())
    return true;  // Treat empty string as the default and do nothing.

  const BuildSettings* build_settings = scope_->settings()->build_settings();
  SourceDir dir = scope_->GetSourceDir().ResolveRelativeDir(
      *value, err_, build_settings->root_path_utf8());
  if (err_->has_error())
    return false;

  target_->set_rebase(dir);
  return true;
}

bool GeneratedFileTargetGenerator::FillDataKeys() {
  const Value* value = scope_->GetValue(variables::kDataKeys, true);
  if (!value)
    return true;
  if (!IsMetadataCollectionTarget(variables::kDataKeys, value->origin()))
    return false;
  if (!value->VerifyTypeIs(Value::LIST, err_))
    return false;

  for (const Value& v : value->list_value()) {
    // Keys must be strings.
    if (!v.VerifyTypeIs(Value::STRING, err_))
      return false;
    target_->data_keys().push_back(v.string_value());
  }

  data_keys_defined_ = true;
  return true;
}

bool GeneratedFileTargetGenerator::FillWalkKeys() {
  const Value* value = scope_->GetValue(variables::kWalkKeys, true);
  // If we define this and contents, that's an error.
  if (value &&
      !IsMetadataCollectionTarget(variables::kWalkKeys, value->origin()))
    return false;

  // If we don't define it, we want the default value which is a list
  // containing the empty string.
  if (!value) {
    target_->walk_keys().push_back("");
    return true;
  }

  // Otherwise, pull and validate the specified value.
  if (!value->VerifyTypeIs(Value::LIST, err_))
    return false;
  for (const Value& v : value->list_value()) {
    // Keys must be strings.
    if (!v.VerifyTypeIs(Value::STRING, err_))
      return false;
    target_->walk_keys().push_back(v.string_value());
  }
  return true;
}
