// Copyright 2016 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 "gn/create_bundle_target_generator.h"

#include <map>

#include "base/logging.h"
#include "gn/filesystem_utils.h"
#include "gn/label_pattern.h"
#include "gn/parse_tree.h"
#include "gn/scope.h"
#include "gn/substitution_type.h"
#include "gn/target.h"
#include "gn/value.h"
#include "gn/value_extractors.h"
#include "gn/variables.h"

CreateBundleTargetGenerator::CreateBundleTargetGenerator(
    Target* target,
    Scope* scope,
    const FunctionCallNode* function_call,
    Err* err)
    : TargetGenerator(target, scope, function_call, err) {}

CreateBundleTargetGenerator::~CreateBundleTargetGenerator() = default;

void CreateBundleTargetGenerator::DoRun() {
  target_->set_output_type(Target::CREATE_BUNDLE);

  BundleData& bundle_data = target_->bundle_data();
  if (!FillBundleDir(SourceDir(), variables::kBundleRootDir,
                     &bundle_data.root_dir()))
    return;
  if (!FillBundleDir(bundle_data.root_dir(), variables::kBundleContentsDir,
                     &bundle_data.contents_dir()))
    return;
  if (!FillBundleDir(bundle_data.root_dir(), variables::kBundleResourcesDir,
                     &bundle_data.resources_dir()))
    return;
  if (!FillBundleDir(bundle_data.root_dir(), variables::kBundleExecutableDir,
                     &bundle_data.executable_dir()))
    return;

  if (!FillXcodeExtraAttributes())
    return;

  if (!FillProductType())
    return;

  if (!FillPartialInfoPlist())
    return;

  if (!FillXcodeTestApplicationName())
    return;

  if (!FillCodeSigningScript())
    return;

  if (!FillCodeSigningSources())
    return;

  if (!FillCodeSigningOutputs())
    return;

  if (!FillCodeSigningArgs())
    return;

  if (!FillBundleDepsFilter())
    return;

  if (!FillXcassetCompilerFlags())
    return;
}

bool CreateBundleTargetGenerator::FillBundleDir(
    const SourceDir& bundle_root_dir,
    std::string_view name,
    SourceDir* bundle_dir) {
  // All bundle_foo_dir properties are optional. They are only required if they
  // are used in an expansion. The check is performed there.
  const Value* value = scope_->GetValue(name, true);
  if (!value)
    return true;
  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;
  std::string str = value->string_value();
  if (!str.empty() && str[str.size() - 1] != '/')
    str.push_back('/');
  if (!EnsureStringIsInOutputDir(GetBuildSettings()->build_dir(), str,
                                 value->origin(), err_))
    return false;
  if (str != bundle_root_dir.value() &&
      !IsStringInOutputDir(bundle_root_dir, str)) {
    *err_ = Err(
        value->origin(), "Path is not in bundle root dir.",
        "The given file should be in the bundle root directory or below.\n"
        "Normally you would do \"$bundle_root_dir/foo\". I interpreted this\n"
        "as \"" +
            str + "\".");
    return false;
  }
  *bundle_dir = SourceDir(std::move(str));
  return true;
}

bool CreateBundleTargetGenerator::FillXcodeExtraAttributes() {
  // Need to get a mutable value to mark all values in the scope as used. This
  // cannot be done on a const Scope.
  Value* value = scope_->GetMutableValue(variables::kXcodeExtraAttributes,
                                         Scope::SEARCH_CURRENT, true);
  if (!value)
    return true;

  if (!value->VerifyTypeIs(Value::SCOPE, err_))
    return false;

  Scope* scope_value = value->scope_value();

  Scope::KeyValueMap value_map;
  scope_value->GetCurrentScopeValues(&value_map);
  scope_value->MarkAllUsed();

  std::map<std::string, std::string> xcode_extra_attributes;
  for (const auto& iter : value_map) {
    if (!iter.second.VerifyTypeIs(Value::STRING, err_))
      return false;

    xcode_extra_attributes.insert(
        std::make_pair(std::string(iter.first), iter.second.string_value()));
  }

  target_->bundle_data().xcode_extra_attributes() =
      std::move(xcode_extra_attributes);
  return true;
}

bool CreateBundleTargetGenerator::FillProductType() {
  const Value* value = scope_->GetValue(variables::kProductType, true);
  if (!value)
    return true;

  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;

  target_->bundle_data().product_type().assign(value->string_value());
  return true;
}

bool CreateBundleTargetGenerator::FillPartialInfoPlist() {
  const Value* value = scope_->GetValue(variables::kPartialInfoPlist, true);
  if (!value)
    return true;

  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;

  const BuildSettings* build_settings = scope_->settings()->build_settings();
  SourceFile path = scope_->GetSourceDir().ResolveRelativeFile(
      *value, err_, build_settings->root_path_utf8());

  if (err_->has_error())
    return false;

  if (!EnsureStringIsInOutputDir(build_settings->build_dir(), path.value(),
                                 value->origin(), err_))
    return false;

  target_->bundle_data().set_partial_info_plist(path);
  return true;
}

bool CreateBundleTargetGenerator::FillXcodeTestApplicationName() {
  const Value* value =
      scope_->GetValue(variables::kXcodeTestApplicationName, true);
  if (!value)
    return true;

  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;

  target_->bundle_data().xcode_test_application_name().assign(
      value->string_value());
  return true;
}

bool CreateBundleTargetGenerator::FillCodeSigningScript() {
  const Value* value = scope_->GetValue(variables::kCodeSigningScript, true);
  if (!value)
    return true;

  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;

  SourceFile script_file = scope_->GetSourceDir().ResolveRelativeFile(
      *value, err_, scope_->settings()->build_settings()->root_path_utf8());
  if (err_->has_error())
    return false;

  target_->bundle_data().set_code_signing_script(script_file);
  return true;
}

bool CreateBundleTargetGenerator::FillCodeSigningSources() {
  const Value* value = scope_->GetValue(variables::kCodeSigningSources, true);
  if (!value)
    return true;

  if (target_->bundle_data().code_signing_script().is_null()) {
    *err_ = Err(
        function_call_,
        "No code signing script."
        "You must define code_signing_script if you use code_signing_sources.");
    return false;
  }

  Target::FileList script_sources;
  if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
                                  scope_->GetSourceDir(), &script_sources,
                                  err_))
    return false;

  target_->bundle_data().code_signing_sources() = std::move(script_sources);
  return true;
}

bool CreateBundleTargetGenerator::FillCodeSigningOutputs() {
  const Value* value = scope_->GetValue(variables::kCodeSigningOutputs, true);
  if (!value)
    return true;

  if (target_->bundle_data().code_signing_script().is_null()) {
    *err_ = Err(
        function_call_,
        "No code signing script."
        "You must define code_signing_script if you use code_signing_outputs.");
    return false;
  }

  if (!value->VerifyTypeIs(Value::LIST, err_))
    return false;

  SubstitutionList& outputs = target_->bundle_data().code_signing_outputs();
  if (!outputs.Parse(*value, err_))
    return false;

  if (outputs.list().empty()) {
    *err_ =
        Err(function_call_,
            "Code signing script has no output."
            "If you have no outputs, the build system can not tell when your\n"
            "code signing script needs to be run.");
    return false;
  }

  // Validate that outputs are in the output dir.
  CHECK_EQ(value->list_value().size(), outputs.list().size());
  for (size_t i = 0; i < value->list_value().size(); ++i) {
    if (!EnsureSubstitutionIsInOutputDir(outputs.list()[i],
                                         value->list_value()[i]))
      return false;
  }

  return true;
}

bool CreateBundleTargetGenerator::FillCodeSigningArgs() {
  const Value* value = scope_->GetValue(variables::kCodeSigningArgs, true);
  if (!value)
    return true;

  if (target_->bundle_data().code_signing_script().is_null()) {
    *err_ = Err(
        function_call_,
        "No code signing script."
        "You must define code_signing_script if you use code_signing_args.");
    return false;
  }

  if (!value->VerifyTypeIs(Value::LIST, err_))
    return false;

  return target_->bundle_data().code_signing_args().Parse(*value, err_);
}

bool CreateBundleTargetGenerator::FillBundleDepsFilter() {
  const Value* value = scope_->GetValue(variables::kBundleDepsFilter, true);
  if (!value)
    return true;

  if (!value->VerifyTypeIs(Value::LIST, err_))
    return false;

  const SourceDir& current_dir = scope_->GetSourceDir();
  std::vector<LabelPattern>& bundle_deps_filter =
      target_->bundle_data().bundle_deps_filter();
  for (const auto& item : value->list_value()) {
    bundle_deps_filter.push_back(LabelPattern::GetPattern(
        current_dir, scope_->settings()->build_settings()->root_path_utf8(),
        item, err_));
    if (err_->has_error())
      return false;
  }

  return true;
}

bool CreateBundleTargetGenerator::FillXcassetCompilerFlags() {
  const Value* value = scope_->GetValue(variables::kXcassetCompilerFlags, true);
  if (!value)
    return true;

  if (!value->VerifyTypeIs(Value::LIST, err_))
    return false;

  return target_->bundle_data().xcasset_compiler_flags().Parse(*value, err_);
}
