# Copyright (c) 2025-2026 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.

if ((defined(ark_standalone_build) && ark_standalone_build) ||
    (defined(ark_static_standalone_build) && ark_static_standalone_build)) {
  import("//arkcompiler/runtime_core/static_core/ark_config.gni")
} else {
  import(
      "//build/config/components/runtime_core/static_core/ark_common_config.gni")
}

if (ark_standalone_build) {
  import("$build_root/ark.gni")
} else {
  import("//build/ohos.gni")
}

npm_path = "//prebuilts/build-tools/common/nodejs/current/bin/npm"

shared_library("ts_bindings") {
  sources = [
    "./native/src/bridges.cpp",
    "./native/src/common-interop.cpp",
    "./native/src/common.cpp",
    "./native/src/convertors-napi.cpp",
    "./native/src/lsp.cpp",
  ]
  if ((defined(ark_standalone_build) && ark_standalone_build) ||
      (defined(ark_static_standalone_build) && ark_static_standalone_build)) {
    configs += [ "$ark_root:ark_config" ]
  } else {
    configs += [
      "//build/config/components/runtime_core/static_core:ark_common_config",
    ]
  }
  configs += [
    "../:libes2panda_public_config",
    "../:libes2panda_config",
  ]

  deps = [
    "../:libes2panda_frontend_static",
    "../lsp:libes2panda_lsp_static",
  ]

  include_dirs = [
    "./native/include",
    "../public/",
    rebase_path("$root_gen_dir/arkcompiler/ets_frontend/ets2panda/"),
    "./node_modules/node-api-headers/include",
  ]

  if (ark_standalone_build) {
    configs += [
      "$ark_root/assembler:arkassembler_public_config",
      "$ark_root/libarkbase:arkbase_public_config",
      "$ark_root/libarkfile:arkfile_public_config",
    ]
    deps += [
      "$ark_root/bytecode_optimizer:libarktsbytecodeopt_frontend_static",
      "$ark_third_party_root/bounds_checking_function:libsec_shared",
    ]
    include_dirs += [ "//third_party/node/src" ]
  } else {
    external_deps = [
      "runtime_core:assembler_headers",
      "runtime_core:libarktsbytecodeopt_package",
      "runtime_core:libpandabase_headers",
      "runtime_core:libpandafile_headers",
      sdk_libc_secshared_dep,
    ]
  }

  defines = [
    "TS_INTEROP_MODULE=NativeModule",
    "INTEROP_LIBRARY_NAME=ts_bindings",
    "TS_USE_NODE_VM",
    "TS_NAPI",
  ]
  if (ark_standalone_build) {
    configs -= [ "$build_root/config/compiler:compiler" ]
  } else {
    configs -= [ "//build/config/compiler:compiler" ]
  }

  if (is_linux) {
    libs = [ "stdc++fs" ]
    cflags_cc = [
      "-std=c++17",
      "-Wall",
      "-Werror",
      "-Wno-unused-variable",
      "-fPIC",
    ]

    ldflags = [
      "-Wl,--allow-shlib-undefined",
      "-Wl,--fatal-warnings",
      "-Wl,--build-id=md5",
      "-fPIC",
      "-Wl,-z,noexecstack",
      "-Wl,-z,now",
      "-Wl,-z,relro",
      "-Wl,--as-needed",
      "-fuse-ld=lld",
      "-Wl,--icf=all",
      "-Wl,--color-diagnostics",
      "-m64",
    ]
    output_extension = "node"
    output_prefix_override = true
  } else if (is_mingw) {
    output_extension = "dll"
    cflags_cc = [
      "-std=c++17",
      "-Wall",
      "-Werror",
      "-Wno-unused-variable",
      "-fPIC",
      "-Wno-error=deprecated-copy",
      "-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang",
      "-ftrivial-auto-var-init=zero",
      "-fcolor-diagnostics",
      "-fmerge-all-constants",
      "-Xclang",
      "-mllvm",
      "-Xclang",
      "-instcombine-lower-dbg-declare=0",
      "-no-canonical-prefixes",
      "-static",
      "-rtlib=compiler-rt",
      "-stdlib=libc++",
      "-lunwind",
      "-lpthread",
      "-Qunused-arguments",
      "-fuse-ld=lld",
      "-fno-stack-protector",
      "-fno-strict-aliasing",
      "-Wno-builtin-macro-redefined",
      "-fms-extensions",
      "-static",
      "-rtlib=compiler-rt",
      "-stdlib=libc++",
      "-std=c++17",
      "-lunwind",
      "-lpthread",
      "-Qunused-arguments",
      "-target",
      "x86_64-pc-windows-gnu",
      "-D__CUSTOM_SECURITY_LIBRARY",
    ]

    ldflags = [
      "-Wl,--fatal-warnings",
      "-fPIC",
      "-Wl,--as-needed",
      "-fuse-ld=lld",
      "-Wl,--icf=all",
      "-m64",
      "-static",
      "-rtlib=compiler-rt",
      "-stdlib=libc++",
      "-std=c++17",
      "-lunwind",
      "-lpthread",
      "-Qunused-arguments",
      "-target",
      "x86_64-pc-windows-gnu",
    ]
    sources += [ "./native/src/win-dynamic-node.cpp" ]
  } else if (is_mac) {
    cflags_cc = [
      "-std=c++17",
      "-Wall",
      "-Werror",
      "-Wno-unused-variable",
      "-fPIC",
    ]

    ldflags = [
      "-fPIC",
      "-fuse-ld=lld",
      "-Wl,--icf=all",
      "-Wl,--color-diagnostics",
      "-m64",
      "-Wl,-undefined,dynamic_lookup",
    ]
    output_extension = "node"
    output_prefix_override = true
  }
}

shared_library("public") {
  sources = [
    "./native/src/bridges.cpp",
    "./native/src/common-interop.cpp",
    "./native/src/common.cpp",
    "./native/src/convertors-napi.cpp",
    "./native/src/lsp.cpp",
  ]

  if ((defined(ark_standalone_build) && ark_standalone_build) ||
      (defined(ark_static_standalone_build) && ark_static_standalone_build)) {
    configs += [ "$ark_root:ark_config" ]
  } else {
    configs += [
      "//build/config/components/runtime_core/static_core:ark_common_config",
    ]
  }

  configs += [
    "../:libes2panda_public_config",
    "../:libes2panda_config",
  ]

  include_dirs = [
    "./native/include",
    "../public/",
    "./node_modules/node-api-headers/include",
    rebase_path("$root_gen_dir/arkcompiler/ets_frontend/ets2panda/"),
  ]
  deps = []
  if (!(defined(ark_static_standalone_build) && ark_static_standalone_build)) {
    deps += [ "../:libes2panda_public_headers" ]
  }
  if (!is_mac) {
    deps += [ "../aot:ets2panda" ]
  }

  if (ark_standalone_build) {
    configs += [
      "$ark_root/assembler:arkassembler_public_config",
      "$ark_root/libarkbase:arkbase_public_config",
      "$ark_root/libarkfile:arkfile_public_config",
    ]
    deps += [
      "$ark_root/bytecode_optimizer:libarktsbytecodeopt_frontend_static",
      "$ark_third_party_root/bounds_checking_function:libsec_shared",
    ]
    include_dirs += [ "//third_party/node/src" ]
  } else {
    external_deps = [
      "runtime_core:assembler_headers",
      "runtime_core:libpandabase_headers",
      "runtime_core:libpandafile_headers",
      sdk_libc_secshared_dep,
    ]
    if (!is_mac) {
      external_deps += [ "runtime_core:libarktsbytecodeopt_package" ]
    }
  }

  defines = [
    "TS_INTEROP_MODULE=NativeModule",
    "INTEROP_LIBRARY_NAME=public",
    "TS_USE_NODE_VM",
    "TS_NAPI",
  ]
  if (ark_standalone_build) {
    configs -= [ "$build_root/config/compiler:compiler" ]
  } else {
    configs -= [ "//build/config/compiler:compiler" ]
  }

  if (is_linux) {
    cflags_cc = [
      "-std=c++17",
      "-Wall",
      "-Werror",
      "-Wno-unused-variable",
      "-fPIC",
    ]

    ldflags = [
      "-Wl,--allow-shlib-undefined",
      "-Wl,--fatal-warnings",
      "-Wl,--build-id=md5",
      "-fPIC",
      "-Wl,-z,noexecstack",
      "-Wl,-z,now",
      "-Wl,-z,relro",
      "-Wl,--as-needed",
      "-fuse-ld=lld",
      "-Wl,--icf=all",
      "-Wl,--color-diagnostics",
      "-m64",
    ]
    output_extension = "node"
    output_prefix_override = true
  } else if (is_mingw) {
    output_extension = "dll"
    cflags_cc = [
      "-std=c++17",
      "-Wall",
      "-Werror",
      "-Wno-unused-variable",
      "-fPIC",
      "-Wno-error=deprecated-copy",
      "-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang",
      "-ftrivial-auto-var-init=zero",
      "-fcolor-diagnostics",
      "-fmerge-all-constants",
      "-Xclang",
      "-mllvm",
      "-Xclang",
      "-instcombine-lower-dbg-declare=0",
      "-no-canonical-prefixes",
      "-static",
      "-rtlib=compiler-rt",
      "-stdlib=libc++",
      "-lunwind",
      "-lpthread",
      "-Qunused-arguments",
      "-fuse-ld=lld",
      "-fno-stack-protector",
      "-fno-strict-aliasing",
      "-Wno-builtin-macro-redefined",
      "-fms-extensions",
      "-static",
      "-rtlib=compiler-rt",
      "-stdlib=libc++",
      "-std=c++17",
      "-lunwind",
      "-lpthread",
      "-Qunused-arguments",
      "-target",
      "x86_64-pc-windows-gnu",
      "-D__CUSTOM_SECURITY_LIBRARY",
    ]

    ldflags = [
      "-Wl,--fatal-warnings",
      "-fPIC",
      "-Wl,--as-needed",
      "-fuse-ld=lld",
      "-Wl,--icf=all",
      "-m64",
      "-static",
      "-rtlib=compiler-rt",
      "-stdlib=libc++",
      "-std=c++17",
      "-lunwind",
      "-lpthread",
      "-Qunused-arguments",
      "-target",
      "x86_64-pc-windows-gnu",
    ]
    sources += [ "./native/src/win-dynamic-node.cpp" ]
  } else if (is_mac) {
    cflags_cc = [
      "-std=c++17",
      "-Wall",
      "-Werror",
      "-Wno-unused-variable",
      "-fPIC",
    ]

    ldflags = [
      "-fPIC",
      "-fuse-ld=lld",
      "-Wl,--icf=all",
      "-Wl,--color-diagnostics",
      "-m64",
      "-Wl,-undefined,dynamic_lookup",
    ]
    output_extension = "node"
    output_prefix_override = true
  }
}

action("build_bindings") {
  deps = [
    ":public",
    ":ts_bindings",
  ]
  sources = [
    "src/common/Es2pandaNativeModule.ts",
    "src/common/InteropNativeModule.ts",
    "src/common/InteropTypes.ts",
    "src/common/Platform.ts",
    "src/common/Wrapper.ts",
    "src/common/arkTSConfigGenerator.ts",
    "src/common/arrays.ts",
    "src/common/driver_helper.ts",
    "src/common/global.ts",
    "src/common/loadLibraries.ts",
    "src/common/mainWrapper.ts",
    "src/common/preDefine.ts",
    "src/common/private.ts",
    "src/common/strings.ts",
    "src/common/ts-reflection.ts",
    "src/common/types.ts",
    "src/common/ui_plugins_driver.ts",
    "src/common/utils.ts",
    "src/generated/Es2pandaEnums.ts",
    "src/generated/Es2pandaNativeModule.ts",
    "src/index.ts",
    "src/lsp/generateArkTSConfig.ts",
    "src/lsp/generateBuildConfig.ts",
    "src/lsp/index.ts",
    "src/lsp/lspNode.ts",
    "src/lsp/lsp_helper.ts",
  ]
  script = "build_bindings.py"

  args = [
    "--source-path",
    rebase_path(get_path_info(".", "abspath")),
    "--output-path",
    rebase_path("$target_gen_dir"),
    "--npm",
    rebase_path(npm_path),
    "--current-os",
    "$current_os",
    "--root-out-dir",
    rebase_path(root_out_dir),
  ]

  outputs = [ "$target_gen_dir" ]
}

ohos_copy("ets2panda_build_bindings") {
  deps = [ ":build_bindings" ]
  sources = [ rebase_path("$target_gen_dir") ]
  outputs = [ target_out_dir + "/$target_name" ]
  module_source_dir = target_out_dir + "/$target_name"
  module_install_name = ""
  part_name = "ets_frontend"
  subsystem_name = "arkcompiler"
}