// 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 "base/strings/stringprintf.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 (!FillPostProcessingScript())
    return;

  if (!FillPostProcessingManifest())
    return;

  if (!FillPostProcessingSources())
    return;

  if (!FillPostProcessingOutputs())
    return;

  if (!FillPostProcessingArgs())
    return;

  if (!FillBundleDepsFilter())
    return;

  if (!FillXcassetCompilerFlags())
    return;

  if (!FillTransparent())
    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.",
            base::StringPrintf("The given file should be in the bundle root "
                               "directory or below.Normally you would do "
                               "\"$bundle_root_dir/foo\". I interpreted this "
                               "as \"%s\".",
                               str.c_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::FillPostProcessingScript() {
  const Value* value = scope_->GetValue(variables::kPostProcessingScript, 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_post_processing_script(script_file);
  return true;
}

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

  if (target_->bundle_data().post_processing_script().is_null()) {
    *err_ = Err(function_call_, "No post-processing script.",
                "You must define post_processing_script if you use "
                "post_processing_manifest.");
    return false;
  }

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

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

  target_->bundle_data().set_post_processing_manifest(manifest_file);
  return true;
}

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

  if (target_->bundle_data().post_processing_script().is_null()) {
    *err_ = Err(function_call_, "No post-processing script.",
                "You must define post_processing_script if you use "
                "post_processing_sources.");
    return false;
  }

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

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

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

  if (target_->bundle_data().post_processing_script().is_null()) {
    *err_ = Err(function_call_, "No post-processing script.",
                "You must define post_processing_script if you use "
                "post_processing_outputs.");
    return false;
  }

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

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

  if (outputs.list().empty()) {
    *err_ = Err(function_call_, "Post-processing script has no output.",
                "If you have no outputs, the build system can not tell when "
                "your post-processing 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::FillPostProcessingArgs() {
  const Value* value = scope_->GetValue(variables::kPostProcessingArgs, true);
  if (!value)
    return true;

  if (target_->bundle_data().post_processing_script().is_null()) {
    *err_ = Err(function_call_, "No post-processing script.",
                "You must define post_processing_script if you use "
                "post_processing_args.");
    return false;
  }

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

  return target_->bundle_data().post_processing_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_);
}

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

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

  target_->bundle_data().set_transparent(value->boolean_value());
  return true;
}
