# Copyright 2018 The Fuchsia 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/compiled_action.gni")
import("//build/package_metadata.gni")

amber_repository_dir = "$root_out_dir/amber-files"

# Directory containing developer signing keys.
amber_keys_dir = "//src/sys/pkg/bin/amber/keys"

# Directory containing files named by their merkleroot content IDs in
# ASCII hex.  The //build/image:pm_publish_blobs target populates
# this with copies of build products, but never removes old files.
amber_repository_blobs_dir = "$amber_repository_dir/repository/blobs"

template("_pm") {
  compiled_action(target_name) {
    tool = "//src/sys/pkg/bin/pm:pm_bin"
    tool_output_name = "pm"
    forward_variables_from(invoker,
                           [
                             "args",
                             "data_deps",
                             "depfile",
                             "deps",
                             "inputs",
                             "metadata",
                             "outputs",
                             "public_deps",
                             "testonly",
                             "visibility",
                           ])
  }
}

# Generate a sealed package file from a manifest.
#
# Parameters
#
#   manifest (required)
#     [label] A generate_manifest() target defined earlier in the same file.
#     This provides the contents for the package.
#
#   The following two items are only required in order to produce metadata about
#   the package sets, and may be removed in the future:
#
#   package_name (required)
#     [string] Name of the package (should match what is in meta/package)
#   package_variant (default: "0")
#     [string] Variant of the package (should match what is in meta/package)
#
#   deps (optional)
#   test (optional)
#   visibility (optional)
#     Same as for any GN `action()` target.
template("pm_build") {
  forward_variables_from(invoker,
                         [
                           "package_name",
                           "package_variant",
                         ])
  assert(defined(package_name), "A package name is required")
  assert(package_name != "", "A package name is required")

  if (!defined(package_variant)) {
    package_variant = "0"
  }

  pkg_out_dir = "$target_out_dir/$target_name"
  pkg_output_manifest = "$pkg_out_dir/package_manifest.json"

  metadata_target_name = "${target_name}_metadata"
  define_package_metadata(metadata_target_name) {
    package_name = package_name
    snapshot_entry = "$package_name/$package_variant=" +
                     rebase_path("$pkg_out_dir/blobs.json", root_build_dir)
    blob_manifest = "$pkg_out_dir/blobs.manifest"
    meta_far_merkle_index_entry =
        "$package_name/$package_variant=" +
        rebase_path("$pkg_out_dir/meta.far.merkle", root_build_dir)
    package_output_manifest = pkg_output_manifest
  }

  _pm(target_name) {
    forward_variables_from(invoker,
                           [
                             "data_deps",
                             "deps",
                             "public_deps",
                             "testonly",
                             "visibility",
                           ])
    if (!defined(deps)) {
      deps = []
    }
    pkg_manifest_outputs = get_target_outputs(invoker.manifest)
    pkg_manifest_file = pkg_manifest_outputs[0]
    deps += [ invoker.manifest ]
    inputs = [ pkg_manifest_file ]
    depfile = "$pkg_out_dir/meta.far.d"

    metadata = {
      if (defined(invoker.metadata)) {
        forward_variables_from(invoker.metadata, "*")
      }
      package_barrier = [ ":$metadata_target_name" ]
    }
    deps += [ ":$metadata_target_name" ]

    outputs = [
      # produced by seal, must be listed first because of depfile rules.
      "$pkg_out_dir/meta.far",

      # update
      "$pkg_out_dir/meta/contents",

      # seal
      "$pkg_out_dir/meta.far.merkle",

      # package blob json manifest
      "$pkg_out_dir/blobs.json",

      # package blob manifest
      "$pkg_out_dir/blobs.manifest",

      # package output manifest
      pkg_output_manifest,
    ]

    args = [
      "-o",
      rebase_path(pkg_out_dir, root_build_dir),
      "-m",
      rebase_path(pkg_manifest_file, root_build_dir),
      "-n",
      package_name,
      "-version",
      package_variant,
      "build",
      "-output-package-manifest",
      rebase_path(pkg_output_manifest, root_build_dir),
      "-depfile",
      "-blobsfile",
      "-blobs-manifest",
    ]

    if (string_replace(package_name, "_", "-") != package_name) {
      # TODO(22679): packages ending up in this allowlist should be updated to
      # use hyphens in their names. New entries should not be added to the
      # allowlist or excluded by logic here.
      deps += [ "//build:deprecated_package_underscore" ]
    }
  }
}

template("pm_publish") {
  # These files are copied from amber_keys_dir into $amber_repository_dir/keys.

  copy("keys") {
    sources = [
      "$amber_keys_dir/snapshot.json",
      "$amber_keys_dir/targets.json",
      "$amber_keys_dir/timestamp.json",
    ]

    outputs = [ "$amber_repository_dir/keys/{{source_file_part}}" ]
  }

  # TODO(38262) In order to be TUF-1.0 conformant, we need to have
  # versioned-prefixed root metadata files. Fow now this just hard-codes
  # copying the current metadata to the correct place, but long term this
  # should be computed so we don't forget to copy the file when we rotate the
  # root metadata.
  copy("root_manifest") {
    sources = [ "$amber_keys_dir/metadata/6.root.json" ]

    outputs = [ "$amber_repository_dir/repository/root.json" ]
  }

  # TODO(38262) See the comment on `root_manifest`.
  copy("versioned_root_manifest") {
    sources = [
      "$amber_keys_dir/metadata/1.root.json",
      "$amber_keys_dir/metadata/2.root.json",
      "$amber_keys_dir/metadata/3.root.json",
      "$amber_keys_dir/metadata/4.root.json",
      "$amber_keys_dir/metadata/5.root.json",
      "$amber_keys_dir/metadata/6.root.json",
    ]

    outputs = [ "$amber_repository_dir/repository/{{source_file_part}}" ]
  }

  _pm(target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "data_deps",
                             "inputs",
                             "testonly",
                             "visibility",
                           ])
    deps += [
      ":keys",
      ":root_manifest",
      ":versioned_root_manifest",
    ]

    depfile = "${target_gen_dir}/${target_name}.d"

    assert(inputs == [ inputs[0] ],
           "pm_publish(\"$target_name\") requires exactly one input")

    outputs = [
      # Note: the first output is the one that appears in the depfile.
      "$amber_repository_dir/repository/timestamp.json",
      "$amber_repository_dir/repository/snapshot.json",
      "$amber_repository_dir/repository/targets.json",
    ]

    args = [
      "publish",
      "-depfile",
      rebase_path(depfile, root_build_dir),
      "-C",
      "-r",
      rebase_path(amber_repository_dir, root_build_dir),
      "-lp",
      "-f",
      rebase_path(inputs[0], root_build_dir),
      "-vt",
    ]
  }
}
