# Copyright (c) 2021 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/python.gni")
import("//build/ohos/build_var.gni")
import("//build/ohos/notice/notice.gni")
import("//build/version.gni")

sdk_base_build_gn = "//build/ohos/sdk/BUILD.gn"
generated_files_dir = get_path_info(sdk_base_build_gn, "gen_dir")
generated_sdk_module_install_paths =
    "${generated_files_dir}/ohos_sdk_install_paths.json"

sdk_system_windows = "windows"
sdk_system_linux = "linux"
sdk_system_darwin = "darwin"
sdk_system_ohos = "ohos"
sdk_system_linux_arm64 = "linux-arm64"

ohos_sdk_out_dir = "$product_output_dir/${product_name}"
ohos_sdk_copy_dir = "$root_build_dir/${product_name}"

declare_args() {
  sdk_check_flag = true
  sdk_for_hap_build = false
}

declare_args() {
  enable_sign = false
  cert_path = ""
}

declare_args() {
  point_split = false
}

sdk_toolchains = {
  windows = "//build/toolchain/mingw:mingw_x86_64"
  ohos = "//build/toolchain/ohos:ohos_clang_arm64"
  linux_arm64 = "//build/toolchain/linux:clang_arm64"

  if (host_cpu == "arm64") {
    linux = "//build/toolchain/linux:clang_arm64"
    darwin = "//build/toolchain/mac:clang_arm64"
  } else {
    linux = "//build/toolchain/linux:clang_x64"
    darwin = "//build/toolchain/mac:clang_x64"
  }
}

if (host_cpu == "arm64") {
  arch = "arm64"
} else if (host_cpu == "riscv64") {
  arch = "riscv64"
} else {
  arch = "x64"
}

if (build_default_sdk_target) {
  if (host_os == "mac") {
    sdk_systems = [ sdk_system_darwin ]
  } else if (host_os == "linux" && host_cpu == "arm64") {
    sdk_systems = [ sdk_system_linux ]
  } else {
    sdk_systems = [
      sdk_system_windows,
      sdk_system_linux,
      sdk_system_ohos,
    ]
  }
} else {
  sdk_systems = []
  if (build_mac_sdk_target) {
    sdk_systems += [ sdk_system_darwin ]
  }
  if (build_windows_sdk_target) {
    sdk_systems += [ sdk_system_windows ]
  }
  if (build_linux_sdk_target) {
    sdk_systems += [ sdk_system_linux ]
  }
  if (build_linux_arm64_sdk_target) {
    sdk_systems += [ sdk_system_linux_arm64 ]
  }
  if (build_ohos_sdk_target) {
    sdk_systems += [ sdk_system_ohos ]
  }
}

if (use_current_sdk) {
  sdk_systems = []
  sdk_systems += [ sdk_system_linux ]
}

template("copy_and_archive") {
  assert(defined(invoker.dest_dir))
  assert(defined(invoker.sdk_system))
  assert(defined(invoker.sdk_type))
  assert(defined(invoker.sdk_modules_desc_file))
  forward_variables_from(invoker,
                         [
                           "testonly",
                           "sdk_class",
                         ])
  action_with_pydeps(target_name) {
    deps = []
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    script = "//build/ohos/sdk/copy_sdk_modules.py"
    depfile = "$target_gen_dir/$target_name.d"

    _sdk_output_archive =
        "$ohos_sdk_out_dir/${invoker.sdk_system}/${invoker.zipfile_name}"
    _notice_output_archive = "${sdk_notice_archive_dir}/${invoker.sdk_system}-${invoker.sdk_type}.zip"

    if (use_current_sdk) {
      _sdk_output_archive = "$ohos_sdk_out_dir/${sdk_class}/${invoker.sdk_system}/${invoker.zipfile_name}"
      _notice_output_archive = "${sdk_notice_archive_dir}/${sdk_class}/${invoker.sdk_system}-${invoker.sdk_type}.zip"
    }

    outputs = [
      _sdk_output_archive,
      _notice_output_archive,
    ]

    args = [
      "--sdk-modules-desc-file",
      rebase_path(invoker.sdk_modules_desc_file, root_build_dir),
      "--dest-dir",
      rebase_path(invoker.dest_dir, root_build_dir),
      "--sdk-output-archive",
      rebase_path(_sdk_output_archive, root_build_dir),
      "--notice-output-archive",
      rebase_path(_notice_output_archive, root_build_dir),
      "--depfile",
      rebase_path(depfile, root_build_dir),
      "--archive-dir",
      rebase_path("${invoker.dest_dir}/${invoker.sdk_type}", root_build_dir),
    ]

    archive_path_args = [
      "--sdk-archive-paths-file",
      rebase_path(generated_sdk_module_install_paths, root_build_dir),
    ]

    if (use_current_sdk) {
      archive_path_args = []
      archive_path_args += [
        "--sdk-archive-paths-file",
        rebase_path(
            "${generated_files_dir}/${sdk_class}/${sdk_class}_sdk_install_paths.json",
            root_build_dir),
      ]
    }

    args += archive_path_args

    if (defined(invoker.zip_prefix_path)) {
      args += [
        "--zip-prefix-path",
        invoker.zip_prefix_path,
      ]
    }

    if (use_current_sdk) {
      enable_archive_sdk = false
    }

    if (enable_archive_sdk) {
      args += [ "--enable-archive-sdk=${enable_archive_sdk}" ]
    }
  }
}

template("make_sdk_modules") {
  assert(defined(invoker.zipfile_name))
  assert(defined(invoker.sdk_modules))
  assert(defined(invoker.sdk_toolchain))
  assert(defined(invoker.sdk_type))
  assert(defined(invoker.sdk_system))

  if (invoker.sdk_modules == []) {
    not_needed(invoker, [ "sdk_toolchain" ])
  }
  copy_and_archive(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "sdk_system",
                             "sdk_type",
                             "zipfile_name",
                             "sdk_class",
                           ])
    _sdk_modules = []
    _sdk_module_infos = []

    foreach(_label, invoker.sdk_modules) {
      _target_label = get_label_info(_label, "label_no_toolchain")
      sources = [ _target_label ]
      if (sources == []) {
        _sdk_modules += [ _target_label ]
      } else {
        _sdk_modules += [ "${_target_label}(${invoker.sdk_toolchain})" ]
      }
      sources = []
    }
    not_needed(invoker, [ "sdk_toolchain" ])

    foreach(_label, _sdk_modules) {
      _module_info_file = get_label_info(_label, "target_out_dir") + "/" +
                          get_label_info(_label, "name") + "_module_info.json"
      _sdk_module_infos += [
        {
          label = get_label_info(_label, "label_no_toolchain")
          module_info_file = rebase_path(_module_info_file, root_build_dir)
        },
      ]
    }
    sdk_modules_desc_file = "${target_gen_dir}/${target_name}_sdk_modules.json"
    write_file(sdk_modules_desc_file, _sdk_module_infos, "json")

    deps = _sdk_modules
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    dest_dir = "${ohos_sdk_copy_dir}/${sdk_system}"
    if (use_current_sdk) {
      dest_dir = "${root_build_dir}/${sdk_class}-current-sdk/${sdk_system}/${api_version}"
    }

    zip_prefix_path = "${invoker.sdk_type}"
  }
}

template("make_linux_sdk_modules") {
  make_sdk_modules(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "zipfile_name",
                             "sdk_modules",
                             "sdk_type",
                             "sdk_class",
                             "deps",
                           ])
    sdk_toolchain = sdk_toolchains.linux
    sdk_system = sdk_system_linux
  }
}

template("make_linux_arm64_sdk_modules") {
  make_sdk_modules(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "zipfile_name",
                             "sdk_modules",
                             "sdk_type",
                             "sdk_class",
                             "deps",
                           ])
    sdk_toolchain = sdk_toolchains.linux_arm64
    sdk_system = sdk_system_linux_arm64
  }
}

template("make_windows_sdk_modules") {
  make_sdk_modules(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "zipfile_name",
                             "sdk_modules",
                             "sdk_type",
                             "sdk_class",
                             "deps",
                           ])
    sdk_toolchain = sdk_toolchains.windows
    sdk_system = sdk_system_windows
  }
}

template("make_darwin_sdk_modules") {
  make_sdk_modules(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "zipfile_name",
                             "sdk_modules",
                             "sdk_type",
                             "sdk_class",
                             "deps",
                           ])
    sdk_toolchain = sdk_toolchains.darwin
    sdk_system = sdk_system_darwin
  }
}

template("make_ohos_sdk_modules") {
  make_sdk_modules(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "zipfile_name",
                             "sdk_modules",
                             "sdk_type",
                             "deps",
                           ])
    sdk_toolchain = sdk_toolchains.ohos
    sdk_system = sdk_system_ohos
  }
}

template("current_sdk") {
  # parse the sdk description file
  forward_variables_from(invoker,
                         [
                           "sdk_desc_file",
                           "sdk_class",
                         ])

  hap_build_sdk_description_file = "${generated_files_dir}/${sdk_class}/${sdk_class}_sdk_description_hap.json"
  hap_build_sdk_config_parser =
      "//build/ohos/sdk/generate_hap_build_sdk_config.py"
  hap_build_sdk_args = [
    "--sdk-description-file",
    rebase_path(sdk_desc_file, root_build_dir),
    "--output-hap-build-sdk-desc-file",
    rebase_path(hap_build_sdk_description_file, root_build_dir),
  ]
  exec_script(hap_build_sdk_config_parser, hap_build_sdk_args)

  sdk_desc_file = hap_build_sdk_description_file
  sdk_parse_script = "//build/ohos/sdk/parse_sdk_description.py"

  gen_sdk_modules_gni =
      "${generated_files_dir}/${sdk_class}/${sdk_class}_sdk_modules.gni"
  gen_sdk_module_install_paths =
      "${generated_files_dir}/${sdk_class}/${sdk_class}_sdk_install_paths.json"
  gen_sdk_types_file =
      "${generated_files_dir}/${sdk_class}/generated_sdk_types.txt"

  parse_args = [
    "--sdk-description-file",
    rebase_path(sdk_desc_file, root_build_dir),
    "--sdk-modules-gni",
    rebase_path(gen_sdk_modules_gni, root_build_dir),
    "--sdk-install-info-file",
    rebase_path(gen_sdk_module_install_paths, root_build_dir),
    "--sdk-types-file",
    rebase_path(gen_sdk_types_file, root_build_dir),
    "--base-platform",
    "phone",
    "--variant-to-product",
    rebase_path("//build/ohos/sdk/variant_to_product.json", root_build_dir),
    "--source-root-dir",
    rebase_path("//", root_build_dir),
    "--node-js",
    rebase_path(nodejs, root_build_dir),
  ]
  foreach(p, target_platform_list) {
    parse_args += [
      "--platforms",
      p,
    ]
  }

  exec_script(sdk_parse_script, parse_args)

  sdk_types = read_file(gen_sdk_types_file, "list lines")

  generate_all_types_sdk_script = "//build/ohos/sdk/generate_all_types_sdk.py"
  generated_build_gn = "${generated_files_dir}/${sdk_class}/BUILD.gn"
  generate_args = [
    "--sdk-modules",
    "ohos_sdk_modules",
    "--output",
    rebase_path(generated_build_gn, root_build_dir),
    "--current-dir",
    get_path_info(sdk_base_build_gn, "dir"),
    "--generated-sdk-modules-gni",
    gen_sdk_modules_gni,
    "--type2displayname",
    rebase_path("//build/ohos/sdk/type_to_display_name.json", root_build_dir),
    "--api-version",
    api_version,
    "--release-type",
    release_type,
    "--meta-version",
    meta_version,
    "--sdk-class",
    sdk_class,
  ]

  if (use_current_sdk) {
    generate_args += [ "--use-current-sdk" ]
  }

  generate_args += [
    "--sdk-systems",
    "linux",
  ]

  foreach(sdk_type, sdk_types) {
    generate_args += [
      "--sdk-types",
      sdk_type,
    ]
  }

  exec_script(generate_all_types_sdk_script, generate_args)

  group(target_name) {
    deps = []
    deps += [ "${generated_files_dir}/${sdk_class}:generated_ohos_sdk" ]
  }
}