# 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("../js_runtime_config.gni")

if (!ark_standalone_build && is_ohos) {
  import("//build/ohos.gni")
}

source_Base = [
  "base/sys_call.cpp",
  "base/c_string.cpp",
  "base/time_utils.cpp",
  "base/mem_utils.cpp",
]
source_Common = [ "common/run_type.cpp" ]

source_Heap = [
  "heap/ark_collector/ark_collector.cpp",
  "heap/ark_collector/copy_barrier.cpp",
  "heap/ark_collector/idle_barrier.cpp",
  "heap/ark_collector/enum_barrier.cpp",
  "heap/ark_collector/marking_barrier.cpp",
  "heap/ark_collector/remark_barrier.cpp",
  "heap/ark_collector/preforward_barrier.cpp",
  "heap/ark_collector/post_marking_barrier.cpp",
  "heap/heap.cpp",
  "heap/allocator/allocator.cpp",
  "heap/allocator/treap.cpp",
  "heap/allocator/memory_map.cpp",
  "heap/allocator/region_manager.cpp",
  "heap/allocator/regional_heap.cpp",
  "heap/allocator/fix_heap.cpp",
  "heap/barrier/barrier.cpp",
  "heap/verification.cpp",
  "heap/collector/collector.cpp",
  "heap/collector/collector_proxy.cpp",
  "heap/collector/collector_resources.cpp",
  "heap/collector/finalizer_processor.cpp",
  "heap/collector/gc_request.cpp",
  "heap/collector/gc_stats.cpp",
  "heap/collector/heuristic_gc_policy.cpp",
  "heap/collector/task_queue.cpp",
  "heap/collector/copy_data_manager.cpp",
  "heap/collector/marking_collector.cpp",
  "heap/collector/utils.cpp",
  "heap/space/from_space.cpp",
  "heap/space/nonmovable_space.cpp",
  "heap/space/large_space.cpp",
  "heap/space/old_space.cpp",
  "heap/space/to_space.cpp",
  "heap/space/young_space.cpp",
  "heap/heap_manager.cpp",
  "common/page_cache.cpp",
]

source_Mutator = [
  "mutator/mutator.cpp",
  "mutator/satb_buffer.cpp",
  "mutator/mutator_manager.cpp",
  "mutator/thread_local.cpp",
]

ohos_source_set("libarkcommon-runtime") {
  configs = [
    "..:ark_jsruntime_public_config",
    "..:ark_jsruntime_common_config",
  ]

  cflags_cc = [ "-Wno-unused-lambda-capture" ]

  sources = []
  sources += source_Base
  sources += source_Common
  sources += source_Heap
  sources += source_Mutator

  include_dirs = []
  include_dirs += [ "./" ]

  # hiviewdfx libraries
  external_deps = hiviewdfx_ext_deps
  if (defined(ohos_indep_compiler_enable) && ohos_indep_compiler_enable) {
    external_deps += [ sdk_libc_secshared_dep ]
  }
  deps = hiviewdfx_deps

  part_name = "ets_runtime"
  subsystem_name = "arkcompiler"
}

config("common_components_public_config") {
  configs = [
    "$ark_root/common_interfaces:common_interfaces_public_config",
    "$ark_root/libpandabase:arkbase_public_config",
    "$ark_root/libpandafile:arkfile_public_config",
  ]
  if (ark_standalone_build ||
      (defined(ohos_indep_compiler_enable) && !ohos_indep_compiler_enable)) {
    configs += [
      "$ark_third_party_root/icu/icu4c:icu_config",
      sdk_libc_secshared_config,
    ]
  }

  include_dirs = [
    "//arkcompiler/ets_runtime",
  ]

  defines = []
  ldflags = []

  if (ark_hybrid) {
    defines += [ "ARK_HYBRID" ]

    if (current_cpu == "amd64" || current_cpu == "x64" ||
        current_cpu == "x86_64") {
      ldflags += [ "-latomic" ]
    }
  }

  if (ark_js_hybrid) {
    defines += [ "PANDA_JS_ETS_HYBRID_MODE" ]
    configs += [ "$ark_root/arkplatform:arkplatform_public_config" ]
  }
}

config("common_components_common_config") {
  configs = [ "//arkcompiler/ets_runtime/:hiviewdfx_config" ]

  defines = [ "PANDA_ENABLE_LTO" ]

  if (ets_runtime_enable_cmc_gc) {
    defines += [ "USE_CMC_GC" ]
    if (is_ohos) {
      defines += [ "ENABLE_COLD_STARTUP_GC_POLICY" ]
    }
  } else {
    defines += [ "CMC_LCOV_EXCL" ]
    print("########## ets_runtime disable cmc-gc ##############")
  }

  if (ark_standalone_build) {
    defines += [ "STANDALONE_MODE" ]
  }

  if (enable_latest_optimization) {
    defines += [ "LATEST_OPTIMIZATION_MACRO" ]
  }

  if (enable_v70_optimization) {
    defines += [ "V70_OPTIMIZATION_MACRO" ]
  }

  cflags_cc = [
    "-Wall",
    "-Wshadow",
    "-Werror",
    "-Wextra",
    "-pedantic",
    "-Wno-invalid-offsetof",
    "-Wno-gnu-statement-expression",
    "-pipe",
    "-Wdate-time",
    "-funwind-tables",
    "-fno-rtti",
    "-fasynchronous-unwind-tables",
    "-Wformat=2",
    "-std=c++17",
  ]

  cflags_cc += [
    "-Wno-unused-command-line-argument",
    "-Wno-variadic-macros",
    "-Wno-gnu-anonymous-struct",
    "-Wno-zero-length-array",
    "-Wno-nested-anon-types",
    "-Wno-c99-extensions",
    "-Wno-unused-parameter",
    "-Wno-shadow",
    "-Wno-pedantic",
    "-Wno-gnu-zero-variadic-macro-arguments",
    "-Wno-unused-lambda-capture",
    "-Wno-unused-function",
    "-Wno-unused-variable",
    "-Wno-unused-but-set-variable",
  ]
  cflags_c = []

  if (is_ohos && is_clang && (target_cpu == "arm" || target_cpu == "arm64")) {
    if (ets_runtime_feature_enable_pgo) {
      cflags = [
        "-fprofile-use=" + rebase_path(
                "${ets_runtime_feature_pgo_path}/libark_jsruntime.profdata",
                root_build_dir),
        "-Wno-error=backend-plugin",
        "-Wno-profile-instr-out-of-date",
        "-Wno-profile-instr-unprofiled",
        "-mllvm",
        "-enable-partial-inlining",
      ]
    }
  }

  if (use_musl) {
    defines += [ "PANDA_USE_MUSL" ]
  }

  if (build_public_version) {
    defines += [ "IS_PUBLIC_VERSION" ]
  }

  if (is_arkui_x) {
    defines += [ "CROSS_PLATFORM" ]
  }

  if (target_os == "android") {
    defines += [ "ANDROID_PLATFORM" ]
  }

  if (is_ohos) {
    defines += [ "PANDA_TARGET_OHOS" ]
  }

  if (is_qemu_runtime && is_ohos) {
    defines += [ "OHOS_FOR_QEMU" ]
  }

  if (use_libfuzzer) {
    defines += [ "FUZZ_TEST" ]
  }

  if (is_fastverify) {
    cflags_cc += [
      "-O3",
      "-ggdb3",
      "-gdwarf-4",
      "-fno-omit-frame-pointer",
      "-D_GLIBCXX_ASSERTIONS",
    ]
    cflags_c += [
      "-O3",
      "-ggdb3",
      "-gdwarf-4",
      "-fno-omit-frame-pointer",
      "-D_GLIBCXX_ASSERTIONS",
    ]
  } else if (is_debug) {
    cflags_cc += [
      "-O0",
      "-ggdb3",
      "-gdwarf-4",
    ]
  } else {
    defines += [ "NDEBUG" ]
  }

  if (enable_asm_assert) {
    defines += [ "ENABLE_ASM_ASSERT" ]
  }

  if (run_with_asan) {
    defines += [ "RUN_WITH_ASAN" ]
  }

  if (enable_cow_array) {
    defines += [ "ENABLE_COW_ARRAY" ]
  }

  if (current_cpu == "arm") {
    defines += [
      "PANDA_TARGET_ARM32_ABI_SOFT=1",
      "PANDA_TARGET_ARM32",
      "PANDA_TARGET_32",
    ]
  } else if (current_cpu == "arm64") {
    defines += [
      "PANDA_TARGET_ARM64",
      "PANDA_TARGET_64",
      "PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES",
      "PANDA_USE_32_BIT_POINTER",
    ]
    if (!is_mingw && !is_mac && target_os != "ios" && !is_arkui_x) {
      defines += [ "EXCLUDE_C_INTERPRETER" ]
    }
  } else if (current_cpu == "x86") {
    defines += [ "PANDA_TARGET_X86" ]
  } else if (current_cpu == "amd64" || current_cpu == "x64" ||
             current_cpu == "x86_64") {
    defines += [
      "PANDA_TARGET_64",
      "PANDA_TARGET_AMD64",
      "PANDA_USE_32_BIT_POINTER",
    ]
  }
  if (enable_ark_intl) {
    defines += [ "ARK_SUPPORT_INTL" ]
  } else {
    if (target_os == "android" || target_os == "ios") {
      defines += [ "ARK_NOT_SUPPORT_INTL_GLOBAL" ]
    } else {
      configs += [ "$global_root/frameworks/intl:intl_util_config" ]
    }
  }

  if (enable_handle_leak_detect) {
    defines += [ "ENABLE_LOCAL_HANDLE_LEAK_DETECT" ]
  }

  if (is_ohos && is_standard_system) {
    defines += [ "ENABLE_EXCEPTION_BACKTRACE" ]

    if (use_musl && (current_cpu == "arm" || current_cpu == "arm64") &&
        !is_mac && !is_mingw && target_os != "ios" && !is_asan) {
      defines += [ "HOOK_ENABLE" ]
    }
  }

  code_encrypto_enable = true
  if (defined(global_parts_info) &&
      !defined(global_parts_info.security_code_crypto_metadata_process)) {
    code_encrypto_enable = false
  }
  if (is_mingw && ark_standalone_build) {
    code_encrypto_enable = false
  }
  if (code_encrypto_enable) {
    defines += [ "CODE_ENCRYPTION_ENABLE" ]
  }
}

# common_components unit testcase config
config("common_components_test_config") {
  visibility = [
    "./*",
  ]

  configs = [
    ":common_components_public_config",
    ":common_components_common_config",
  ]

  if (enable_handle_leak_detect) {
    defines = [ "ENABLE_LOCAL_HANDLE_LEAK_DETECT" ]
  }
  if (!is_mac) {
    ldflags = [ "-Wl,-rpath=\$ORIGIN/" ]
  } else {
    ldflags = [ "-Wl" ]
  }

  if (!ark_standalone_build) {
    ldflags += [ "-Wl,--lto-O0" ]
  }
}

ohos_shared_library("libark_common_components_test") {
  testonly = true
  stack_protector_ret = false

  configs = [ ":common_components_test_config" ]

  sources = [
    "common_runtime/base_runtime.cpp",
    "common_runtime/base_runtime_param.cpp",
    "base/utf_helper.cpp",
    "heap/heap_allocator.cpp",
    "log/log.cpp",
    "objects/base_object.cpp",
    "objects/base_string_table.cpp",
    "objects/base_string.cpp",
    "objects/composite_base_class.cpp",
    "taskpool/taskpool.cpp",
    "taskpool/runner.cpp",
    "taskpool/task_queue.cpp",
    "tests/test_hooks.cpp",
    "heap/heap_visitor.cpp",
    "profiler/heap_profiler_listener.cpp",
    "thread/thread_holder.cpp",
    "thread/thread_holder_manager.cpp",
    "platform/unix/map.cpp",
  ]

  if (is_mingw) {
    sources += [
      "platform/windows/cpu.cpp",
      "platform/windows/os.cpp",
    ]
  } else if (is_mac) {
    sources += [
      "platform/unix/mac/cpu.cpp",
      "platform/unix/mac/os.cpp",
    ]
  } else if (is_ohos || target_os == "android") {
    sources += [
      "platform/unix/linux/cpu.cpp",
      "platform/unix/linux/os.cpp",
    ]
  } else if (is_linux) {
    sources += [
      "platform/unix/linux/cpu.cpp",
      "platform/unix/linux/os.cpp",
    ]
  }

  deps = [ ":libarkcommon-runtime" ]

  public_configs = [ ":common_components_public_config" ]
  public_configs += [ "//arkcompiler/ets_runtime:include_llvm" ]

  external_deps = []
  if (!ark_standalone_build) {
    public_external_deps = [
      "zlib:libz",
      "bounds_checking_function:libsec_shared",
    ]
    public_external_deps += hiviewdfx_ext_deps
  } else {
    external_deps += [
      "zlib:libz",
      "bounds_checking_function:libsec_shared",
    ]
    external_deps += hiviewdfx_ext_deps
  }

  ldflags = []
  if (enable_coverage) {
    ldflags += [ "--coverage" ]
    cflags_cc = [ "--coverage" ]
  }
  if (!ark_standalone_build) {
    ldflags += [ "-Wl,--lto-O0" ]
  }

  install_enable = false
  if (!is_mingw && !is_mac) {
    output_extension = "so"
  }

  if (!is_arkui_x) {
    external_deps += [ "runtime_core:libarkfile_runtime_static" ]
  } else {
    deps += [ "$ark_root/libpandafile:libarkfile_runtime_static" ]
  }

  part_name = "ets_runtime"
  subsystem_name = "arkcompiler"
}

ohos_shared_library("libark_common_components_fuzz_test") {
  testonly = true
  stack_protector_ret = false

  configs = [ ":common_components_test_config" ]

  sources = [
    "log/log.cpp",
    "base/utf_helper.cpp",
  ]

  if (is_mingw) {
    sources += [
      "platform/windows/cpu.cpp",
      "platform/windows/os.cpp",
    ]
  } else if (is_mac) {
    sources += [
      "platform/unix/mac/cpu.cpp",
      "platform/unix/mac/os.cpp",
    ]
  } else if (is_ohos || target_os == "android") {
    sources += [
      "platform/unix/linux/cpu.cpp",
      "platform/unix/linux/os.cpp",
    ]
  } else if (is_linux) {
    sources += [
      "platform/unix/linux/cpu.cpp",
      "platform/unix/linux/os.cpp",
    ]
  }

  # deps = [ ":libarkcommon-runtime" ]

  public_configs = [ ":common_components_public_config" ]
  public_configs += [ "//arkcompiler/ets_runtime:include_llvm" ]

  external_deps = []
  if (!ark_standalone_build) {
    public_external_deps = [
      "zlib:libz",
    ]
    public_external_deps += hiviewdfx_ext_deps
  } else {
    external_deps += [
      "zlib:libz",
    ]
    external_deps += hiviewdfx_ext_deps
  }

  ldflags = []
  if (enable_coverage) {
    ldflags += [ "--coverage" ]
    cflags_cc = [ "--coverage" ]
  }
  if (!ark_standalone_build) {
    ldflags += [ "-Wl,--lto-O0" ]
  }

  install_enable = false
  if (!is_mingw && !is_mac) {
    output_extension = "so"
  }

  if (!is_arkui_x) {
    external_deps += [ "runtime_core:libarkfile_runtime_static" ]
  } else {
    deps = [ "$ark_root/libpandafile:libarkfile_runtime_static" ]
  }

  part_name = "ets_runtime"
  subsystem_name = "arkcompiler"
}