# Copyright 2021 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

_is_python2 = exec_script("//build/util/is_python2.py", [], "json")
assert(!_is_python2, "`python` must resolve to Python 3 when building with GN.")

declare_args() {
  is_clang = true

  build_type = "devel"

  is_starboard = true

  cobalt_fastbuild = getenv("IS_CI") == "1"

  is_internal_build = getenv("COBALT_USE_INTERNAL_BUILD") == "1"

  is_docker_build = getenv("IS_DOCKER") == "1"

  using_old_compiler = false
}

is_debug = build_type == "debug"
is_devel = build_type == "devel"
is_qa = build_type == "qa"
is_gold = build_type == "gold"
assert(is_debug || is_devel || is_qa || is_gold)

# Set some variables we never want to change.
sb_allows_memory_tracking = !is_gold
host_byteorder = "little"
is_official_build = false  # Chromium's build files expect this to be set.
is_component_build = false

# The os/cpu definitions are here to set the current platform type in
# os_definitions.gni below.
if (target_os == "") {
  target_os = host_os
}
if (target_cpu == "") {
  target_cpu = host_cpu
}
if (current_os == "") {
  current_os = target_os
}
if (current_cpu == "") {
  current_cpu = target_cpu
}
import("//starboard/build/config/os_definitions.gni")

if (is_mac) {
  declare_args() {
    use_system_xcode = true
  }
}

# Get the path to the starboard implementation and include its GN
# configuration.
import("//starboard/build/platform_path.gni")
host_toolchain = "//$starboard_path/toolchain:host"
target_toolchain = "//$starboard_path/toolchain:target"
set_default_toolchain(target_toolchain)

import("//$starboard_path/platform_configuration/configuration.gni")
import("//starboard/build/config/build_assertions.gni")

declare_args() {
  use_tsan = getenv("USE_TSAN") == 1
}

_use_asan_default = (is_debug || is_devel) && (is_linux || is_mac) &&
                    is_clang && !sb_is_evergreen && !using_old_compiler
declare_args() {
  use_asan = (_use_asan_default || getenv("USE_ASAN") == 1) && !use_tsan
}

assert(!(use_tsan && use_asan), "ASAN and TSAN are mutually exclusive.")

# =============================================================================
# TARGET DEFAULTS
# =============================================================================
#
# Set up the default configuration for every build target of the given type.
# The values configured here will be automatically set on the scope of the
# corresponding target. Target definitions can add or remove to the settings
# here as needed.
#
# WHAT GOES HERE?
#
# Other than the main compiler and linker configs, the only reason for a config
# to be in this list is if some targets need to explicitly override that config
# by removing it. This is how targets opt-out of flags. If you don't have that
# requirement and just need to add a config everywhere, reference it as a
# sub-config of an existing one, most commonly the main "compiler" one.

default_compiler_configs = [
  "//build/config/compiler:default_include_dirs",
  "//build/config/compiler:no_exceptions",
  "//starboard/build/config:base",
  "//starboard/build/config:host",
  "//starboard/build/config:size",
  "//starboard/build/config:target",
  "//starboard/build/config:warnings_as_errors",
  "//starboard/build/config:default_compiler_flags",
]

if (use_thin_archive) {
  default_compiler_configs += [ "//build/config/compiler:thin_archive" ]
}

if (is_starboard) {
  default_compiler_configs += [ "//starboard/build/config:starboard" ]
}

if (is_qa || is_gold || sb_use_no_rtti) {
  default_compiler_configs += [ "//build/config/compiler:no_rtti" ]
}

if (is_win) {
  default_compiler_configs += [ "//build/config/win:lean_and_mean" ]
}

set_defaults("static_library") {
  configs = default_compiler_configs + static_library_configs
  has_pedantic_warnings = false
}
set_defaults("source_set") {
  configs = default_compiler_configs + source_set_configs
  has_pedantic_warnings = false
}
set_defaults("loadable_module") {
  configs = default_compiler_configs + loadable_module_configs
  has_pedantic_warnings = false
}
set_defaults("executable") {
  configs = default_compiler_configs + executable_configs
  has_pedantic_warnings = false
}
set_defaults("shared_library") {
  configs = default_compiler_configs + shared_library_configs
  has_pedantic_warnings = false
}

# We make sure to change the pedantic_warnings configs in a particular order to
# ensure -Wno-foo compiler flags (usually set in no_pedantic_warnings and some
# of the platform_configuration) come after -Wfoo flags (including -Wall and
# -Wextra which are set in pedantic_warnings). It is only certain the the "foo"
# error will be ignored if -Wfoo precedes -Wno-foo in the compilation line.
template("target_with_platform_configs") {
  target(invoker.target_type, target_name) {
    forward_variables_from(invoker, "*", [ "target_type" ])

    if (has_pedantic_warnings) {
      configs += [ "//starboard/build/config:pedantic_warnings" ]
    }
    configs += [ "//$starboard_path/platform_configuration" ]
    if (!has_pedantic_warnings) {
      configs += [ "//starboard/build/config:no_pedantic_warnings" ]
    }
  }
}

# Ensure the platform_configuration config is the last one included.
template("static_library") {
  target_with_platform_configs(target_name) {
    target_type = "static_library"
    forward_variables_from(invoker, "*")
  }
}

template("source_set") {
  target_with_platform_configs(target_name) {
    target_type = "source_set"
    forward_variables_from(invoker, "*")
  }
}

template("loadable_module") {
  target_with_platform_configs(target_name) {
    target_type = "loadable_module"
    forward_variables_from(invoker, "*")
  }
}

# Import configuration variables needed for the install targets and install
# content targets.
import("//starboard/build/config/install.gni")

# Template for copying content files to the install directory.
template("install_content") {
  target(invoker.target_type, target_name) {
    forward_variables_from(invoker, "*", [ "install_content" ])
    if (defined(visibility)) {
      visibility += [ ":${target_name}_install_content" ]
    }
  }

  if (defined(invoker.install_content) && invoker.install_content) {
    # We're using a custom script to copy the files here because rebase_path
    # can't be used with {{}} expansions in the outputs of a copy target.
    action("${target_name}_install_content") {
      forward_variables_from(invoker, [ "testonly" ])

      deps = [ ":${invoker.target_name}" ]

      sources = get_target_outputs(":${invoker.target_name}")

      # List of files in metadata so they can be forwarded for bundling.
      metadata = {
        install_content = sources

        # Don't inherit any metadata from upstream deps.
        ignore_install_content = deps
      }

      install_content_dir = "$sb_install_output_dir/$sb_install_content_subdir"
      outputs = []
      foreach(source, sources) {
        output_path = install_content_dir + "/" +
                      rebase_path(source, sb_static_contents_output_data_dir)
        outputs += [ output_path ]
      }

      # Write the file list to a unique temp file to avoid blowing out the
      # command line length limit.
      files_list = "$root_gen_dir/${target_name}_files.tmp"
      write_file(files_list, rebase_path(sources, root_build_dir))

      script = "//starboard/build/copy_install_content.py"
      args = [
        "--output_dir",
        rebase_path(install_content_dir, root_build_dir),
        "--base_dir",
        rebase_path(sb_static_contents_output_data_dir, root_build_dir),
        "--files_list",
        rebase_path(files_list, root_build_dir),
      ]
    }
  }
}

# Set up the method of generating the install targets as defined by the
# platform.
import("$install_target_path")
template("action") {
  install_content(target_name) {
    forward_variables_from(invoker, "*")
    target_type = "action"
  }
}

template("action_foreach") {
  install_content(target_name) {
    forward_variables_from(invoker, "*")
    target_type = "action_foreach"
  }
}

template("copy") {
  install_content(target_name) {
    forward_variables_from(invoker, "*")
    target_type = "copy"
  }
}

template("executable") {
  target_with_platform_configs(target_name) {
    target_type = "executable"
    forward_variables_from(invoker, "*", [ "install_target" ])
  }

  if (current_toolchain == default_toolchain &&
      (!defined(invoker.install_target) || invoker.install_target)) {
    executable_target_name = target_name

    data_deps = []
    if (defined(invoker.data_deps)) {
      data_deps += invoker.data_deps
    }
    if (defined(platform_i18n_config_path)) {
      data_deps += [ platform_i18n_config_path ]
    }

    if (separate_install_targets_for_bundling) {
      import("//starboard/build/config/bundle_content.gni")
      bundle_content("${executable_target_name}_bundle_content") {
        forward_variables_from(invoker, [ "testonly" ])

        bundle_name = executable_target_name
        bundle_deps = data_deps
      }
    }

    install_target(target_name + "_install") {
      forward_variables_from(invoker, [ "testonly" ])
      installable_target_name = executable_target_name
      type = "executable"
      deps = []
      if (defined(invoker.deps)) {
        deps += invoker.deps
      }
      foreach(dep, data_deps) {
        deps += [ "${dep}_install_content" ]
      }
      if (separate_install_targets_for_bundling) {
        deps += [ ":${executable_target_name}_bundle_content" ]
      }
    }
  }
}

template("shared_library") {
  target_with_platform_configs(target_name) {
    target_type = "shared_library"
    forward_variables_from(invoker, "*", [ "install_target" ])
  }

  if (current_toolchain == default_toolchain &&
      (!defined(invoker.install_target) || invoker.install_target)) {
    shared_library_target_name = target_name

    data_deps = []
    if (defined(invoker.data_deps)) {
      data_deps += invoker.data_deps
    }
    if (defined(platform_i18n_config_path)) {
      data_deps += [ platform_i18n_config_path ]
    }

    if (separate_install_targets_for_bundling) {
      import("//starboard/build/config/bundle_content.gni")
      bundle_content("${shared_library_target_name}_bundle_content") {
        forward_variables_from(invoker, [ "testonly" ])

        bundle_name = shared_library_target_name
        bundle_deps = []
        bundle_deps = data_deps
      }
    }

    install_target(target_name + "_install") {
      forward_variables_from(invoker, [ "testonly" ])
      installable_target_name = shared_library_target_name
      type = "shared_library"
      deps = []
      if (defined(invoker.deps)) {
        deps += invoker.deps
      }
      foreach(dep, data_deps) {
        deps += [ "${dep}_install_content" ]
      }
      if (separate_install_targets_for_bundling) {
        deps += [ ":${shared_library_target_name}_bundle_content" ]
      }
    }
  }
}

# Import this down here as it relies on variables set during configuration.
import("//starboard/build/config/components.gni")
