# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# 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.

import("//arkcompiler/runtime_core/ark_root.gni")

if (is_standard_system) {
  import("$ark_root/platforms/ohos/ark_config.gni")
} else {
  import("$ark_root/platforms/common/ark_config.gni")
}

if (!defined(is_host_product)) {
  is_host_product = false
}

declare_args() {
  enabled_plugins = default_enabled_plugins
  enabled_pac_data_protect = false
}

if (!ark_standalone_build && !(defined(is_arkui_x) && is_arkui_x) && is_ohos &&
    is_standard_system && target_cpu == "arm64" && !is_emulator &&
    defined(global_parts_info) &&
    defined(global_parts_info.security_code_signature)) {
  enabled_pac_data_protect = true
}

if (current_cpu == "arm") {
  if (!defined(arm_float_abi) || arm_float_abi == "") {
    arm_float_abi = "softfp"
  }

  assert(arm_float_abi == "soft" || arm_float_abi == "softfp" ||
             arm_float_abi == "hard",
         "arm_float_abi should be soft, softfp or hard")
}

# We don't support x64 compiler in GN build, since asmjit is not available here
ark_enable_compiler_x64 = false

ark_enable_global_register_variables = true
enable_bytecode_optimizer = true
enable_relayout_profile = false

sdk_libc_secshared_dep = "bounds_checking_function:libsec_shared"
sdk_libc_secshared_config =
    "$ark_third_party_root/bounds_checking_function:libsec_public_config"

if (is_mingw || is_mac || is_linux || target_os == "ios" ||
    target_os == "android" || (is_build_sdk && is_ohos) ||
    (defined(ohos_indep_compiler_enable) && ohos_indep_compiler_enable)) {
  sdk_libc_secshared_dep = "bounds_checking_function:libsec_static"
}

zlib_deps = "zlib:shared_libz"
if (defined(ohos_indep_compiler_enable) && ohos_indep_compiler_enable) {
  zlib_deps = "zlib:libz"
}

is_mob = !ark_standalone_build && !is_standard_system &&
         (current_cpu != "arm" || is_wearable_product)

enable_hilog =
    !ark_standalone_build && is_standard_system && current_os == "ohos" &&
    (current_cpu == "arm64" || current_cpu == "arm")

## TODO add other arch

# Generate file for a template and YAML data provided.
#
# Mandatory arguments:
# data_file -- YAML data full name
# template_file -- template full name
# output_file -- output file full name
# requires -- a list of scripts that provide data-querying API for templates
# extra_dependencies -- a list of files that should be considered as dependencies, must be lable
template("ark_gen_file") {
  assert(defined(invoker.data_file), "data_file is required!")
  assert(defined(invoker.template_file), "template_file is required!")
  assert(defined(invoker.output_file), "output_file is required!")

  requires = ""
  if (defined(invoker.requires)) {
    requires = string_join(",", rebase_path(invoker.requires, root_build_dir))
  }

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

  positional_argv = []
  if (defined(invoker.extra_argv)) {
    positional_argv += invoker.extra_argv
  }
  keyword_argv = [
    "--template",
    rebase_path(invoker.template_file, root_build_dir),
    "--data",
    rebase_path(invoker.data_file, root_build_dir),
    "--require",
    requires,
    "--output",
    rebase_path(invoker.output_file),
  ]

  action("$target_name") {
    script = "$ark_root/isa/gen.rb"

    # rerun action when data file or template file update
    inputs = [
      invoker.template_file,
      invoker.data_file,
    ]
    if (defined(invoker.requires)) {
      inputs += invoker.requires
    }
    outputs = [ invoker.output_file ]
    args = positional_argv + keyword_argv
    deps = extra_dependencies
  }
}

template("concat_yamls") {
  assert(defined(invoker.output_file), "output_file is required!")
  assert(defined(invoker.default_file), "default_file is required!")

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

  outputs = [ invoker.output_file ]

  action("$target_name") {
    script = "$ark_root/templates/concat_yamls.sh"

    # rerun action when data file or template file update
    inputs = [ invoker.default_file ]
    if (defined(invoker.add_yamls)) {
      inputs += invoker.add_yamls
    }

    args = [
      rebase_path(invoker.output_file, root_build_dir),
      rebase_path(invoker.default_file, root_build_dir),
    ]

    foreach(yaml, invoker.add_yamls) {
      args += [ rebase_path(yaml, root_build_dir) ]
    }

    deps = extra_dependencies
  }
}

template("merge_yamls") {
  assert(defined(invoker.output_file), "output_file is required!")
  assert(defined(invoker.add_yamls), "add_yamls is required!")

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

  # rerun action when data file or template file update
  inputs = invoker.add_yamls
  outputs = [ invoker.output_file ]

  action("$target_name") {
    script = "$ark_root/templates/merge.rb"

    data = []
    foreach(yaml, invoker.add_yamls) {
      data += [ rebase_path(yaml, root_build_dir) ]
    }
    args = [
      "-d",
      string_join(",", data),
      "-o",
      rebase_path(invoker.output_file, root_build_dir),
    ]

    deps = extra_dependencies
  }
}

# Generate files based on templates and YAML data provided.
# Adds targets for every template. Also adds a target for the whole function invocation
# with name ${data_name}_gen_${PROJECT_NAME} for ease of declaring dependencies on generated files.
#
# Mandatory arguments:
# * data -- data source, YAML file
# * template_files -- a list of templates to generate files
# * requires -- a list of Ruby scripts that provide data-querying API for templates
#
# Optional arguments:
# * sources -- a directory with templates, default is ${PROJECT_SOURCE_DIR}/templates
# * destination -- a directory for output files, default is ${PANDA_BINARY_ROOT}
# * extra_dependencies -- a list of files that should be considered as dependencies
# * extra_argv -- a list of positional arguments that could be accessed in '.erb' files via ARGV[]
template("ark_gen") {
  assert(defined(invoker.data), "data were not passed to ark_gen")
  assert(defined(invoker.template_files),
         "template_files were not passed to ark_gen")

  dir = ""
  if (defined(invoker.sources)) {
    dir = invoker.sources
  } else {
    dir = "templates"
  }

  destination = ""
  if (defined(invoker.destination)) {
    destination = invoker.destination
  } else {
    destination = target_out_dir
  }

  input_requires = ""
  if (defined(invoker.requires)) {
    input_requires = invoker.requires
  }

  foreach(t, invoker.template_files) {
    name = string_replace(t, ".erb", "")
    output = "${destination}/${name}"
    name = string_replace(name, ".", "_")
    name = string_replace(name, "/", "_")
    target = "${target_name}_${name}"

    ark_gen_file(target) {
      data_file = invoker.data
      template_file = "${dir}/${t}"
      output_file = output
      requires = input_requires
      extra_dependencies = []
      if (defined(invoker.extra_dependencies)) {
        extra_dependencies += invoker.extra_dependencies
      }
      extra_argv = []
      if (defined(invoker.extra_argv)) {
        extra_argv += invoker.extra_argv
      }
    }
  }
}

# Calls `ark_gen` for ISA YAML.
# Adds targets for every template. Also adds a target for the whole function invocation
# with name isa_gen_${PROJECT_NAME} for ease of declaring dependencies on generated files.
#
# Mandatory arguments:
# * template_files -- a list of templates to generate files
#
# Optional arguments:
# * sources -- a directory with templates, default is ${PROJECT_SOURCE_DIR}/templates
# * destination -- a directory for output files, default is ${target_out_dir}
# * requires -- if defined, will require additional Ruby files for template generation, must be list
# * extra_dependencies -- a list of files that should be considered as dependencies lable, must be list, not used
template("ark_isa_gen") {
  isa_data = "$root_gen_dir/isa/isa.yaml"
  isa_requires = [ "$ark_root/isa/isapi.rb" ]
  if (defined(invoker.requires)) {
    isa_requires += invoker.requires
  }

  dependencies = [ "$ark_root/isa:isa_combine" ]
  if (defined(invoker.extra_dependencies)) {
    dependencies += invoker.extra_dependencies
  }

  ark_gen("$target_name") {
    data = isa_data
    template_files = invoker.template_files
    sources = invoker.sources
    destination = invoker.destination
    requires = isa_requires
    extra_dependencies = dependencies
  }
}