# Copyright 2013 The Flutter 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/fuchsia/config.gni")
import("//flutter/tools/fuchsia/fuchsia_debug_symbols.gni")
import("//flutter/tools/fuchsia/fuchsia_libs.gni")
import("//flutter/tools/fuchsia/gn-sdk/config/config.gni")

# Compiles a CML file for a V2 component.
#
# manifest (required):
#   The path to the .cml file for the component. Should include the file extension.
# output (optional):
#   The path for the output .cm file. Should include the file extension.
template("_compile_cml") {
  assert(defined(invoker.manifest), "_compile_cml must define manifest")

  action(target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "testonly",
                             "visibility",
                           ])
    script = "//flutter/tools/fuchsia/compile_cml.py"

    inputs = [ "$fuchsia_tool_dir/cmc" ]
    sources = [ invoker.manifest ]

    args = [
      "--cmc-bin",
      rebase_path("$fuchsia_tool_dir/cmc"),
      "--manifest-file",
      rebase_path(invoker.manifest),
      "--output",
      rebase_path(invoker.output, root_build_dir),
      "--includepath",
      rebase_path("$fuchsia_sdk/pkg/", root_build_dir),
      "--includepath",
      get_path_info(invoker.manifest, "dir"),
      "--includepath",
      rebase_path("//"),
    ]
    outputs = [ invoker.output ]
  }
}

# Creates a Fuchsia archive (.far) file using PM from the Fuchsia SDK.
#
# binary (required):
#   The ELF binary for the archive's program.
# cmx_file (optional):
#   The path to the V1 component manifest (.cmx file) for the archive's component.
#   Should include the file extension.
# cml_file (optional):
#   The path to the V2 component manifest (.cml file) for the archive's component.
#   Should include the file extension.
# deps (optional):
#   The code dependencies for the archive.
# inputs (optional):
#   When these files are changed, the package should be regenerated.
# libraries (optional):
#   Paths to .so libraries that should be dynamically linked to the binary.
# resources (optional):
#   Files that should be placed into the `data/` directory of the archive.
# testonly (optional):
#   Set this to true for archives that are only used for tests.
template("_fuchsia_archive") {
  assert(defined(invoker.binary), "package must define binary")

  pkg_testonly = defined(invoker.testonly) && invoker.testonly
  pkg_target_name = target_name
  pkg = {
    package_version = "0"  # placeholder
    forward_variables_from(invoker,
                           [
                             "binary",
                             "deps",
                             "resources",
                             "libraries",
                           ])
    if (!defined(package_name)) {
      package_name = pkg_target_name
    }
    if (!defined(deps)) {
      deps = []
    }
    if (!defined(resources)) {
      resources = []
    }
    if (!defined(libraries)) {
      libraries = []
    }
  }

  far_base_dir = "$root_out_dir/${pkg_target_name}_far"

  copy_sources = [ "$root_out_dir/${invoker.binary}" ]
  copy_outputs = [ "$far_base_dir/bin/app" ]

  foreach(res, pkg.resources) {
    copy_sources += [ res.path ]
    copy_outputs += [ "$far_base_dir/data/${res.dest}" ]
  }

  foreach(lib, pkg.libraries) {
    copy_sources += [ "${lib.path}/${lib.name}" ]
    copy_outputs += [ "$far_base_dir/lib/${lib.name}" ]
  }

  pkg_dir_deps = pkg.deps

  if (defined(invoker.cmx_file)) {
    # cmx files are used for v1 components, only copy it if it is defined
    cmx_file = invoker.cmx_file

    cmx_target = "$pkg_target_name.copy_cmx"

    copy("$cmx_target") {
      sources = [ "$cmx_file" ]
      outputs = [ "$far_base_dir/meta/${pkg_target_name}.cmx" ]
    }

    pkg_dir_deps += [ ":$cmx_target" ]
  }

  write_file("${far_base_dir}/meta/package",
             {
               name = pkg.package_name
               version = pkg.package_version
             },
             "json")

  _dbg_symbols_target = "${target_name}_dbg_symbols"
  fuchsia_debug_symbols(_dbg_symbols_target) {
    deps = pkg.deps
    testonly = pkg_testonly
    binary = invoker.binary
  }

  action("${target_name}_dir") {
    script = "//flutter/tools/fuchsia/copy_path.py"
    sources = copy_sources
    response_file_contents = rebase_path(copy_sources + copy_outputs)
    deps = pkg_dir_deps
    args = [ "--file-list={{response_file_name}}" ]
    outputs = copy_outputs
    testonly = pkg_testonly
  }

  manifest_json_file = "${root_out_dir}/${target_name}_package_manifest.json"
  action(target_name) {
    script = "//flutter/tools/fuchsia/gen_package.py"
    deps = pkg_dir_deps + [
             ":${target_name}_dir",
             ":${_dbg_symbols_target}",
           ]

    sources = copy_outputs

    inputs = []
    if (defined(invoker.inputs)) {
      inputs += invoker.inputs
    }

    args = [
      "--pm-bin",
      rebase_path("$fuchsia_tool_dir/pm"),
      "--package-dir",
      rebase_path(far_base_dir),
      "--far-name",
      target_name,
      "--manifest-json-file",
      rebase_path(manifest_json_file, root_build_dir),
    ]

    assert(fuchsia_target_api_level != -1,
           "Must set a target api level when creating an archive")
    if (fuchsia_target_api_level != -1) {
      args += [
        "--api-level",
        "${fuchsia_target_api_level}",
      ]
    }

    outputs = [
      manifest_json_file,
      "${far_base_dir}.manifest",
      "$root_out_dir/${target_name}-0.far",
    ]
    testonly = pkg_testonly
  }
}

# Creates a Fuchsia archive.
#
# An archive combines an ELF binary and a component manifest to create
# a packaged Fuchsia program that can be deployed to a Fuchsia device.
#
# binary (required):
#   The ELF binary for the archive's program.
# cmx_file (required if cml_file is not set):
#   The V1 component manifest for the Fuchsia component.
# cml_file (required if cmx_file is not set):
#   The V2 component manifest for the Fuchsia component.
# deps (optional):
#   The code dependencies for the archive.
# inputs (optional):
#   When these files are changed, the package should be regenerated.
# libraries (optional):
#   Paths to .so libraries that should be dynamically linked to the binary.
# resources (optional):
#   Files that should be placed into the `data/` directory of the archive.
# testonly (optional):
#   Set this to true for archives that are only used for tests.
template("fuchsia_archive") {
  assert(defined(invoker.cmx_file) || defined(invoker.cml_file),
         "must specify either a cmx file, cml file or both")
  _deps = []
  if (defined(invoker.deps)) {
    _deps += invoker.deps
  }

  if (defined(invoker.cml_file)) {
    _far_base_dir = "$root_out_dir/${target_name}_far"
    _cml_file_name = get_path_info(invoker.cml_file, "name")
    _compile_cml_target = "${target_name}_${_cml_file_name}_compile_cml"

    _compile_cml(_compile_cml_target) {
      forward_variables_from(invoker, [ "testonly" ])

      manifest = invoker.cml_file
      output = "$_far_base_dir/meta/${_cml_file_name}.cm"
    }
    _deps += [ ":$_compile_cml_target" ]
  }

  _fuchsia_archive(target_name) {
    deps = _deps
    forward_variables_from(invoker,
                           [
                             "binary",
                             "cmx_file",
                             "inputs",
                             "libraries",
                             "resources",
                             "testonly",
                           ])
  }
}

# Creates a Fuchsia archive (.far) file containing a generated test root
# component and test driver component, using PM from the Fuchsia SDK.
#
# binary (required):
#   The binary for the test.
# deps (required):
#   Dependencies for the test archive.
# cmx_file (optional):
#   A path to the .cmx file for the test archive.
#   If not defined, a generated .cml file for the test archive will be used instead.
# cml_file (optional):
#   The path to the V2 component manifest (.cml file) for the test archive's component.
#   Should include the file extension.
#   If not defined, a generated .cml file for the test archive will be used instead.
# libraries (optional):
#   Paths to .so libraries that should be dynamically linked to the binary.
# resources (optional):
#   Files that should be placed into the `data/` directory of the archive.
template("fuchsia_test_archive") {
  assert(defined(invoker.deps), "package must define deps")
  _deps = []
  if (defined(invoker.deps)) {
    _deps += invoker.deps
  }

  if (defined(invoker.cml_file)) {
    _far_base_dir = "$root_out_dir/${target_name}_far"
    _cml_file_name = get_path_info(invoker.cml_file, "name")
    _compile_cml_target = "${target_name}_${_cml_file_name}_compile_cml"

    _compile_cml(_compile_cml_target) {
      forward_variables_from(invoker, [ "testonly" ])

      manifest = invoker.cml_file
      output = "$_far_base_dir/meta/${_cml_file_name}.cm"
    }
    _deps += [ ":$_compile_cml_target" ]
  } else {
    # Interpolate test_suite.cml template with the test suite's name.
    test_suite = target_name
    interpolate_cml_target = "${test_suite}_interpolate_cml"
    generated_cml_file = "$root_out_dir/$test_suite.cml"
    action(interpolate_cml_target) {
      testonly = true
      script = "//flutter/tools/fuchsia/interpolate_test_suite.py"
      sources = [ "//flutter/testing/fuchsia/meta/test_suite.cml" ]
      args = [
        "--input",
        rebase_path("//flutter/testing/fuchsia/meta/test_suite.cml"),
        "--test-suite",
        test_suite,
        "--output",
        rebase_path(generated_cml_file),
      ]
      outputs = [ generated_cml_file ]
    }

    far_base_dir = "$root_out_dir/${target_name}_far"

    # Compile the resulting interpolated test suite's cml.
    compile_test_suite_cml_target = "${test_suite}_test_suite_compile_cml"
    _compile_cml(compile_test_suite_cml_target) {
      testonly = true
      deps = [ ":$interpolate_cml_target" ]

      manifest = generated_cml_file
      output = "$far_base_dir/meta/${test_suite}.cm"
    }

    _deps += [ ":$compile_test_suite_cml_target" ]
  }

  _fuchsia_archive(target_name) {
    testonly = true
    forward_variables_from(invoker,
                           [
                             "binary",
                             "resources",
                           ])

    libraries = common_libs
    if (defined(invoker.libraries)) {
      libraries += invoker.libraries
    }

    deps = _deps
  }
}
