# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/buildflag_header.gni")
import("//build/config/ios/rules.gni")
import("//build/config/mac/symbols.gni")
import("//build/mac/tweak_info_plist.gni")
import("//components/cronet/native/include/headers.gni")
import("//components/grpc_support/include/headers.gni")
import("//testing/test.gni")
import("//url/features.gni")

assert(!is_component_build, "Cronet requires static library build.")

group("cronet_consumer_group") {
  deps = [
    "//components/cronet/ios/cronet_consumer",
  ]
}

config("cronet_include_config") {
  include_dirs = [ "//components/grpc_support/include" ]
}

config("cronet_static_config") {
  libs = [
    "Cronet.framework",
    "UIKit.Framework",
    "CFNetwork.framework",
    "MobileCoreServices.framework",
    "Security.framework",
    "SystemConfiguration.framework",
    "resolv",
  ]
  configs = [ ":cronet_include_config" ]
}

_cronet_deps = [
  ":generate_accept_languages",
  "//base:base",
  "//components/cronet:cronet_common",
  "//components/cronet:cronet_version_header",
  "//components/cronet/native:cronet_native_impl",
  "//components/grpc_support",
  "//components/prefs:prefs",
  "//ios/net:net",
  "//ios/web/public:user_agent",
  "//ios/web/public/global_state",
  "//net",
  "//url",
]

_cronet_sources = [
  "Cronet.h",
  "Cronet.mm",
  "cronet_environment.h",
  "cronet_environment.mm",
  "cronet_global_state_ios.mm",
  "cronet_metrics.h",
  "cronet_metrics.mm",
]

_cronet_public_headers = [ "Cronet.h" ]
_cronet_public_headers += grpc_public_headers
_cronet_public_headers += cronet_native_public_headers

source_set("cronet_sources") {
  deps = _cronet_deps

  sources = _cronet_sources

  include_dirs = [ "//components/grpc_support/include" ]

  if (!use_platform_icu_alternatives) {
    deps += [ "//base:i18n" ]
  }

  configs += [ "//build/config/compiler:enable_arc" ]
}

source_set("cronet_sources_with_global_state") {
  deps = [
    "//base",
    "//ios/web/public/global_state",
  ]

  public_deps = [
    ":cronet_sources",
  ]

  sources = [
    "ios_global_state_configuration.cc",
  ]
}

# Tweak |info_plist| with current version and revision.
tweak_info_plist("tweak_cronet_plist") {
  info_plist = "Info.plist"
}

ios_framework_bundle("cronet_framework") {
  output_name = "Cronet"
  info_plist_target = ":tweak_cronet_plist"

  deps = [
    ":cronet_sources_with_global_state",
    "//base",
    "//net:net",
  ]

  libs = [ "UIKit.Framework" ]

  public_deps = [
    "//components/grpc_support",
  ]

  public_headers = _cronet_public_headers

  sources = [
    "Cronet.h",
  ]

  configs -= [ "//build/config/compiler:default_symbols" ]
  configs += [ "//build/config/compiler:symbols" ]

  public_configs = [ ":cronet_include_config" ]
}

test("cronet_unittests_ios") {
  testonly = true

  sources = []

  deps = [
    ":cronet_sources_with_global_state",
    "//base",
    "//base/test:test_support",
    "//components/cronet:cronet_common_unittests",
    "//components/cronet/native:cronet_native_unittests",
    "//components/metrics",
    "//net",
    "//testing/gtest",
  ]

  bundle_deps = [ "//components/cronet/ios/test:cronet_test" ]
}

action("generate_accept_languages") {
  script = "//components/cronet/tools/generate_accept_languages.py"
  args = [
    rebase_path("$target_gen_dir"),
    rebase_path("//"),
  ]
  outputs = [
    "$target_gen_dir/accept_languages_table.h",
  ]
}

# A static library which contains just _cronet_sources.
static_library("cronet_static") {
  visibility = [ ":*" ]
  deps = _cronet_deps
  sources = _cronet_sources + [ "ios_global_state_configuration.cc" ]
  public_configs = [ ":cronet_include_config" ]
  public_deps = [
    "//components/grpc_support",
  ]
  configs += [ "//build/config/compiler:enable_arc" ]
}

# A static library which contains all dependencies of :cronet_static.
static_library("cronet_deps_complete") {
  visibility = [ ":*" ]
  complete_static_lib = true
  configs -= [ "//build/config/compiler:thin_archive" ]
  deps = [
    ":cronet_static",
  ]
}

# A static library which contains cronet and all dependendencies hidden inside.
action("cronet_static_complete") {
  visibility = [ ":*" ]
  script = "//components/cronet/tools/hide_symbols.py"
  deps = [
    ":cronet_deps_complete",
    ":cronet_static",
  ]
  outputs = [
    "$target_out_dir/$current_cpu/cronet_static_complete.a",
  ]
  args = [
    "--input_libs",
    rebase_path("$target_out_dir/libcronet_static.a", root_build_dir),
    "--deps_lib",
    rebase_path("$target_out_dir/libcronet_deps_complete.a", root_build_dir),
    "--output_obj",
    rebase_path("$target_out_dir/$current_cpu/cronet_static_complete.o",
                root_build_dir),
    "--output_lib",
    rebase_path("$target_out_dir/$current_cpu/cronet_static_complete.a",
                root_build_dir),
    "--current_cpu",
    current_cpu,
  ]

  if (!use_system_xcode) {
    args += [
      "--developer_dir",
      hermetic_xcode_path,
    ]
  }

  public_configs = [ ":cronet_static_config" ]
}

# A fat static library which exports cronet public symbols and hides all dependendencies.
lipo_binary("libcronet") {
  arch_binary_target = ":cronet_static_complete"
  arch_binary_output = "cronet_static_complete.a"
  output_name = "libcronet.a"
  enable_stripping = false
  enable_dsyms = false
}

template("ios_static_framework") {
  _target_name = target_name
  _output_name = target_name
  if (defined(invoker.output_name)) {
    _output_name = invoker.output_name
  }
  _framework_name = target_name
  if (defined(invoker.framework_name)) {
    _framework_name = invoker.framework_name
  }

  _framework_headers_target = _target_name + "_framework_headers"
  bundle_data(_framework_headers_target) {
    visibility = [ ":$_target_name" ]
    sources = invoker.public_headers
    outputs = [
      "{{bundle_contents_dir}}/Headers/{{source_file_part}}",
    ]
  }

  _framework_binary_target = _target_name + "_framework_binary"
  _static_library_target = invoker.static_library_target

  bundle_data(_framework_binary_target) {
    visibility = [ ":$_target_name" ]
    sources = get_target_outputs(_static_library_target)
    outputs = [
      "{{bundle_executable_dir}}/$_framework_name",
    ]
    public_deps = [
      _static_library_target,
    ]
  }

  create_bundle(_target_name) {
    product_type = "com.apple.product-type.framework"
    bundle_root_dir = "$root_out_dir/Static/${_output_name}"
    bundle_contents_dir = bundle_root_dir
    bundle_executable_dir = bundle_contents_dir
    bundle_resources_dir = bundle_contents_dir
    bundle_plugins_dir = bundle_contents_dir
    deps = [
      ":$_framework_binary_target",
      ":$_framework_headers_target",
    ]
    public_configs = invoker.public_configs
  }
}

ios_static_framework("cronet_static_framework") {
  output_name = "Cronet.framework"
  framework_name = "Cronet"
  public_headers = _cronet_public_headers
  static_library_target = ":libcronet"
  public_configs = [ ":cronet_static_config" ]
}

if (additional_toolchains == [] || current_toolchain == default_toolchain) {
  _package_dir = "$root_out_dir/cronet"

  action("generate_license") {
    _license_path = "$_package_dir/LICENSE"

    script = "//tools/licenses.py"
    inputs = [
      "//build/util/LASTCHANGE",
    ]
    outputs = [
      _license_path,
    ]
    args = [
      "license_file",
      rebase_path(_license_path, root_build_dir),
      "--gn-target",
      "//components/cronet/ios:cronet_framework",
      "--gn-out-dir",
      ".",
    ]
  }

  copy("cronet_static_copy") {
    sources = [
      "$root_out_dir/Static/Cronet.framework",
    ]
    outputs = [
      "$_package_dir/Static/Cronet.framework",
    ]

    deps = [
      ":cronet_static_framework",
    ]
  }

  copy("cronet_package_copy") {
    sources = [
      "$root_out_dir/Cronet.framework",
      "//AUTHORS",
      "//chrome/VERSION",
    ]
    outputs = [
      "$_package_dir/{{source_file_part}}",
    ]

    deps = [
      ":cronet_framework",
      ":cronet_static_copy",
    ]
  }

  if (enable_dsyms) {
    action("cronet_dsym_archive") {
      script = "//chrome/tools/build/mac/archive_symbols.py"

      # These are the dSYMs that will be archived. The sources list must be
      # the target outputs that correspond to the dSYMs (since a dSYM is a
      # directory it cannot be listed as a source file). The targets that
      # generate both the dSYM and binary image are listed in deps.
      _dsyms = [ "$root_out_dir/Cronet.dSYM" ]

      sources = [
        "$root_out_dir/Cronet.framework",
      ]

      _output = "$_package_dir/Cronet.dSYM.tar.bz2"

      outputs = [
        _output,
      ]

      args = [ rebase_path(_output, root_out_dir) ] +
             rebase_path(_dsyms, root_out_dir)

      deps = [
        ":cronet_framework",
      ]
    }
  } else {
    group("cronet_dsym_archive") {
    }
  }

  group("cronet_package") {
    deps = [
      ":cronet_dsym_archive",
      ":cronet_package_copy",
      ":generate_license",
    ]
  }
}
