# Copyright (c) 2025 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("//build/config/components/ets_frontend/ets_frontend_config.gni")
import("//build/ohos/taihe_idl/taihe_args.gni")

declare_args() {
  ets_static_abc_bypass = !support_jsapi
}

ets2abc_root = "ets_frontend"
ets2abc_build_path = ""
ets2abc_build_deps = ""
ets2abc_out_root = ""
static_linker_root = "runtime_core"
static_linker_build_path = ""
static_linker_build_deps = ""
static_linker_out_root = ""
libes2panda_public_build_deps = ""
ohos_ets_koala_wrapper_deps = ""
ohos_ets_libarkts_deps = ""
libes2panda_public_build_path = ""
ohos_ets_libes2panda_public_path = ""
bootpath_json_file = ""

if (host_toolchain == toolchain_mac) {
  ets2abc_out_root =
      get_label_info("$ets2abc_root:ets2panda($toolchain_mac)", "root_out_dir")
  ets2abc_build_deps = "$ets2abc_root:ets2panda($toolchain_mac)"
  static_linker_out_root =
      get_label_info("$static_linker_root:ark_link($toolchain_mac)",
                     "root_out_dir")
  static_linker_build_deps = "$static_linker_root:ark_link($toolchain_mac)"
  libes2panda_public_build_deps =
      "$ets2abc_root:libes2panda_public($toolchain_mac)"
  ohos_ets_koala_wrapper_deps =
      "ace_ets2bundle:ohos_ets_koala_wrapper($toolchain_mac)"
  ohos_ets_libarkts_deps = "ace_ets2bundle:ohos_ets_libarkts($toolchain_mac)"
  libes2panda_public_build_path =
      static_linker_out_root + "/arkcompiler/ets_frontend/libes2panda_public.so"
  ohos_ets_libes2panda_public_path =
      "$root_build_dir/ohos_ets/build-tools/ets2panda/lib/libes2panda_public.so"
} else if (host_toolchain == toolchain_win) {
  ets2abc_out_root =
      get_label_info("$ets2abc_root:ets2panda($toolchain_win)", "root_out_dir")
  ets2abc_build_deps = "$ets2abc_root:ets2panda($toolchain_win)"
  static_linker_out_root =
      get_label_info("$static_linker_root:ark_link($toolchain_win)",
                     "root_out_dir")
  static_linker_build_deps = "$static_linker_root:ark_link($toolchain_win)"
  libes2panda_public_build_deps =
      "$ets2abc_root:libes2panda_public($toolchain_win)"
  ohos_ets_koala_wrapper_deps =
      "ace_ets2bundle:ohos_ets_koala_wrapper($toolchain_win)"
  ohos_ets_libarkts_deps = "ace_ets2bundle:ohos_ets_libarkts($toolchain_win)"
  libes2panda_public_build_path =
      static_linker_out_root +
      "/arkcompiler/ets_frontend/libes2panda_public.dll"
  ohos_ets_libes2panda_public_path = "$root_build_dir/ohos_ets/build-tools/ets2panda/lib/libes2panda_public.dll"
} else {
  ets2abc_out_root = get_label_info("$ets2abc_root:ets2panda($toolchain_linux)",
                                    "root_out_dir")
  ets2abc_build_deps = "$ets2abc_root:ets2panda($toolchain_linux)"
  static_linker_out_root =
      get_label_info("$static_linker_root:ark_link($toolchain_linux)",
                     "root_out_dir")
  static_linker_build_deps = "$static_linker_root:ark_link($toolchain_linux)"
  libes2panda_public_build_deps =
      "$ets2abc_root:libes2panda_public($toolchain_linux)"
  ohos_ets_koala_wrapper_deps =
      "ace_ets2bundle:ohos_ets_koala_wrapper($toolchain_linux)"
  ohos_ets_libarkts_deps = "ace_ets2bundle:ohos_ets_libarkts($toolchain_linux)"
  libes2panda_public_build_path =
      static_linker_out_root + "/arkcompiler/ets_frontend/libes2panda_public.so"
  ohos_ets_libes2panda_public_path =
      "$root_build_dir/ohos_ets/build-tools/ets2panda/lib/libes2panda_public.so"
}
ets2abc_build_path = ets2abc_out_root + "/arkcompiler/ets_frontend/es2panda"
static_linker_build_path =
    static_linker_out_root + "/arkcompiler/runtime_core/ark_link"

build_sdk_path = "$root_build_dir/ohos_ets"

ohos_ets_etsstdlib_deps = "runtime_core:ohos_ets_etsstdlib_abc"
ohos_ets_etsstdlib_path =
    "$build_sdk_path/build-tools/ets2panda/lib/etsstdlib.abc"

ohos_ets_kits_deps = "sdk:ohos_ets_kits"
ohos_ets_api_deps = "sdk:ohos_ets_api"
ohos_ets_arkts_deps = "sdk:ohos_ets_arkts"
ohos_ets_stdlib_deps = "runtime_core:ohos_ets_stdlib"
ohos_ets_es2panda_deps =
    "//build/config/components/ets_frontend:ohos_ets_es2panda"
ohos_ets_ark_link_deps =
    "//build/config/components/ets_frontend:ohos_ets_ark_link"
ohos_ets_libes2panda_public_deps =
    "//build/config/components/ets_frontend:ohos_ets_libes2panda_public"
ohos_ets_build_system_deps = "ets_frontend:ohos_ets_build_system"
ohos_ets_dependency_analyzer_deps = "ets_frontend:ohos_ets_dependency_analyzer"
ohos_ets_ui_plugins_deps = "ace_ets2bundle:ohos_ets_ui_plugins"

ohos_ets_api_tmp_path = "$root_build_dir/ohos_ets_tmp/api"
ohos_ets_api_arkui_tmp_path = "$root_build_dir/ohos_ets_tmp/api/arkui/component"
ohos_ets_arkts_tmp_path = "$root_build_dir/ohos_ets_tmp/arkts"
ohos_ets_kits_tmp_path = "$root_build_dir/ohos_ets_tmp/kits"
ohos_ets_api_path = "$root_build_dir/ohos_ets/api"
ohos_ets_api_arkui_path = "$root_build_dir/ohos_ets/api/arkui/component"
ohos_ets_arkts_path = "$root_build_dir/ohos_ets/arkts"
ohos_ets_kits_path = "$root_build_dir/ohos_ets/kits"
ohos_ets_inner_path = "$root_build_dir/ohos_ets/inner"
ohos_ets_es2panda_path =
    "$root_build_dir/ohos_ets/build-tools/ets2panda/bin/es2panda"
ohos_ets_ark_link_path =
    "$root_build_dir/ohos_ets/build-tools/ets2panda/bin/ark_link"
ohos_ets_stdlib_path =
    "$root_build_dir/ohos_ets/build-tools/ets2panda/lib/stdlib"
ohos_ets_build_system_path =
    "$root_build_dir/ohos_ets/build-tools/driver/build-system"
ohos_ets_dependency_analyzer_path =
    "$root_build_dir/ohos_ets/build-tools/ets2panda/bin/dependency_analyzer"
ohos_ets_ui_plugins_path = "$root_build_dir/ohos_ets/build-tools/ui-plugins"
ohos_ets_koala_wrapper_path =
    "$root_build_dir/ohos_ets/build-tools/koala-wrapper"
ohos_ets_libarkts_path = "$root_build_dir/ohos_ets/build-tools/libarkts"

if (host_os == "mac") {
  if (host_cpu == "arm64") {
    node_path =
        "//prebuilts/build-tools/common/nodejs/node-v18.20.1-darwin-arm64/bin"
  } else {
    node_path =
        "//prebuilts/build-tools/common/nodejs/node-v18.20.1-darwin-x64/bin"
  }
} else {
  node_path =
      "//prebuilts/build-tools/common/nodejs/node-v18.20.1-linux-x64/bin"
}

if (ohos_indep_compiler_enable && (string_replace(ohos_indep_compiler_components, "runtime_core", "") == ohos_indep_compiler_components)) {
  ark_link_target_out_path =
      get_label_info(static_linker_build_deps, "target_out_dir") +
      "/clang_x64/libs/ark_link"
} else {
  ark_link_target_out_path = "$static_linker_build_path"
}

if (ohos_indep_compiler_enable && (string_replace(ohos_indep_compiler_components, "ets_frontend", "") == ohos_indep_compiler_components)) {
  ets2panda_target_out_path =
      get_label_info(ets2abc_build_deps, "target_out_dir") +
      "/clang_x64/libs/es2panda"
  libes2panda_public_out_path =
      get_label_info(libes2panda_public_build_deps, "target_out_dir") +
      "/clang_x64/libs/libes2panda_public.so"
} else {
  ets2panda_target_out_path = "$ets2abc_build_path"
  libes2panda_public_out_path = "$libes2panda_public_build_path"
}

bootpath_json_file = root_out_dir + "/obj/arkcompiler/ets_frontend/ets2panda/aot/build/config/components/ets_frontend/bootpath.json"

template("generate_static_abc") {
  _dst_file = "$target_out_dir/$target_name.abc"
  if (defined(invoker.dst_file)) {
    _dst_file = invoker.dst_file
  }
  _outputs = []
  if (defined(invoker.out_puts)) {
    _outputs = invoker.out_puts
  } else {
    _outputs = [ _dst_file ]
  }
  _is_static_abc_bypass_target = ets_static_abc_bypass
  if (!_is_static_abc_bypass_target && taihe_template_bypass &&
      defined(invoker.base_url) &&
      string_replace(invoker.base_url, "$root_out_dir/taihe", "") !=
          invoker.base_url) {
    _is_static_abc_bypass_target = true
  }
  if (_is_static_abc_bypass_target) {
    not_needed(invoker, "*")
    action("$target_name") {
      if (defined(invoker.extra_visibility)) {
        visibility = invoker.extra_visibility
      }
      script = "//build/scripts/touch_outputs.py"
      args = rebase_path(_outputs, root_build_dir)
      outputs = _outputs
    }
  } else {
    dependencies = []
    external_dependencies = []
    if (defined(invoker.dependencies)) {
      dependencies += invoker.dependencies
    }
    if (defined(invoker.external_dependencies)) {
      external_dependencies += invoker.external_dependencies
    }
    action("$target_name") {
      if (defined(invoker.extra_visibility)) {
        visibility = invoker.extra_visibility
      }

      script = "//build/config/components/ets_frontend/generate_static_abc.py"

      deps = dependencies
      deps += [
        ohos_ets_ark_link_deps,
        ohos_ets_es2panda_deps,
      ]
      external_deps = external_dependencies
      external_deps += [
        ohos_ets_etsstdlib_deps,
        ohos_ets_stdlib_deps,
      ]

      args = [
        "--bootpath-json-file",
        rebase_path("${bootpath_json_file}"),
      ]

    ui_enable = "False"
    if (defined(invoker.ui_enable)) {
      ui_enable = invoker.ui_enable
    }
    args += [
      "--ui-enable",
      ui_enable,
    ]

    if (ui_enable == "False") {
      args += [
        "--es2panda",
        rebase_path("$ohos_ets_es2panda_path"),
        "--ark-link",
        rebase_path("$ohos_ets_ark_link_path"),
        "--env-path",
        rebase_path("${static_linker_out_root}/arkcompiler/runtime_core/"),
      ]
    }

    if (ui_enable == "True") {
      assert(defined(invoker.files), "files is required!")
      assert(defined(invoker.base_url), "base_url is required!")
      deps += [ ohos_ets_libes2panda_public_deps ]
      external_deps += [
        ohos_ets_api_deps,
        ohos_ets_arkts_deps,
        ohos_ets_build_system_deps,
        ohos_ets_kits_deps,
        ohos_ets_koala_wrapper_deps,
        ohos_ets_ui_plugins_deps,
      ]
      if (!is_mac) {
        external_deps += [ ohos_ets_libarkts_deps ]
      }
      args += [
        "--base-url",
        rebase_path("${invoker.base_url}"),
        "--build-sdk-path",
        rebase_path("$build_sdk_path"),
        "--memo-plugin",
        rebase_path(
            "$build_sdk_path/build-tools/ui-plugins/lib/memo-plugins/index.js"),
        "--entry-path",
        rebase_path(
            "$build_sdk_path/build-tools/driver/build-system/dist/entry.js"),
        "--env-path",
        rebase_path("$build_sdk_path/build-tools/ets2panda/lib"),
        "--node-path",
        rebase_path("$node_path"),
        "--scan-path",
        rebase_path("$ohos_ets_api_path"),
        rebase_path("$ohos_ets_arkts_path"),
        rebase_path("$ohos_ets_kits_path"),
      ]
      if (defined(invoker.enable_inner_path) && invoker.enable_inner_path) {
        args += [ rebase_path("$ohos_ets_inner_path") ]
      }

      only_memo = "False"
      if (defined(invoker.only_memo)) {
        only_memo = invoker.only_memo
      }

      # if set only_memo, skip other plugins
      if (only_memo != "True") {
        args += [
          "--ui-plugin",
          rebase_path(
              "$build_sdk_path/build-tools/ui-plugins/lib/ui-plugins/index.js"),
        ]
      }

      file_paths = []
      foreach(path, invoker.files) {
        file_paths += [ rebase_path(path) ]
      }
      file_list_file = "${target_out_dir}/${target_name}_file_list.txt"
      write_file(file_list_file, file_paths)
      args += [
        "--files",
        rebase_path(file_list_file),
      ]

      if (defined(invoker.package)) {
        args += [
          "--package",
          invoker.package,
        ]
      }

      if (defined(invoker.paths_keys) && defined(invoker.paths_values)) {
        args += [ "--paths-keys" ] + invoker.paths_keys
        paths_values = []
        foreach(path, invoker.paths_values) {
          paths_values += [ rebase_path(path) ]
        }
        args += [ "--paths-values" ] + paths_values
      }
    } else if (defined(invoker.base_url)) {
      external_deps += [
        ohos_ets_api_deps,
        ohos_ets_arkts_deps,
      ]
      args += [
        "--base-url",
        rebase_path("${invoker.base_url}"),
        "--root-dir",
        rebase_path("//"),
        "--scan-path",
        rebase_path("$ohos_ets_api_path"),
        rebase_path("$ohos_ets_arkts_path"),
        rebase_path("$ohos_ets_inner_path"),
        "--std-path",
        rebase_path("$ohos_ets_stdlib_path/std"),
        "--escompat-path",
        rebase_path("$ohos_ets_stdlib_path/escompat"),
      ]

      if (defined(invoker.paths_keys) && defined(invoker.paths_values)) {
        args += [ "--paths-keys" ] + invoker.paths_keys
        paths_values = []
        foreach(path, invoker.paths_values) {
          paths_values += [ rebase_path(path) ]
        }
        args += [ "--paths-values" ] + paths_values
      }

      if (defined(invoker.include)) {
        include_paths = []
        foreach(path, invoker.include) {
          include_paths += [ rebase_path(path) ]
        }
        args += [ "--include" ] + include_paths
      }

      if (defined(invoker.exclude)) {
        exclude_paths = []
        foreach(path, invoker.exclude) {
          exclude_paths += [ rebase_path(path) ]
        }
        args += [ "--exclude" ] + exclude_paths
      }

      if (defined(invoker.files)) {
        file_paths = []
        foreach(path, invoker.files) {
          file_paths += [ rebase_path(path) ]
        }
        file_list_file = "${target_out_dir}/${target_name}_file_list.txt"
        write_file(file_list_file, file_paths)
        args += [
          "--files",
          rebase_path(file_list_file),
        ]
      }

      if (defined(invoker.package)) {
        args += [
          "--package",
          invoker.package,
        ]
      }
    }

    if (defined(invoker.timeout_limit)) {
      args += [
        "--timeout-limit",
        invoker.timeout_limit,
      ]
    }

    if (defined(invoker.is_stdlib)) {
      args += [
        "--is-stdlib",
        invoker.is_stdlib,
      ]
    }

    if (defined(invoker.is_boot_abc)) {
      args += [
        "--is-boot-abc",
        invoker.is_boot_abc,
      ]
      if (invoker.is_boot_abc == "True") {
        assert(
            defined(invoker.device_dst_file),
            "The 'device_dst_file' parameter is required if 'is_boot_abc' is True!")
        args += [
          "--device-dst-file",
          invoker.device_dst_file,
          "--target-name",
          "$target_name",
        ]
      }
    }

    cache_path = "$target_out_dir/$target_name/cache"
    if (defined(invoker.cache_path)) {
      cache_path = invoker.cache_path
    }
    args += [
      "--cache-path",
      rebase_path(cache_path),
    ]

    arktsconfig = "$target_out_dir/$target_name.json"
    if (defined(invoker.arktsconfig)) {
      arktsconfig = invoker.arktsconfig
    }
    args += [
      "--arktsconfig",
      rebase_path(arktsconfig),
    ]

      dst_file = _dst_file
      args += [
        "--dst-file",
        rebase_path(dst_file),
      ]

      if (defined(invoker.in_puts)) {
        inputs = invoker.in_puts
      }

      outputs = _outputs
    }
  }
}