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

# Defines a guest package.
#
# Parameters
#   zircon (string, optional)
#     Path to a Zircon kernel. Either "zircon" or "linux" must be specified.
#   linux (string, optional)
#     Path to a Linux kernel. Either "zircon" or "linux" must be specified.
#   ramdisk (string, optional)
#     Path to a ramdisk file to be loaded into the guest.
#   cmdline (string, optional)
#     Kernel cmdline string.
#   dtb_overlay (string, optional)
#     Path to a DTB overlay to be loaded for a Linux kernel.
#   block_devices (array, optional)
#     List of block devices to use.
#
template("guest_package") {
  assert(defined(invoker.zircon) || defined(invoker.linux), "")

  guest_config_target_name = "${target_name}_guest_config"
  guest_config_file = "${target_out_dir}/guest.cfg"

  action(guest_config_target_name) {
    testonly = defined(invoker.testonly) && invoker.testonly

    script = "//src/virtualization/packages/generate_guest_config.py"
    outputs = [ guest_config_file ]

    args = []
    if (defined(invoker.zircon)) {
      args += [
        "--zircon",
        "data/kernel",
      ]
    }
    if (defined(invoker.linux)) {
      args += [
        "--linux",
        "data/kernel",
      ]
    }
    if (defined(invoker.ramdisk)) {
      args += [
        "--ramdisk",
        "data/ramdisk",
      ]
    }
    if (defined(invoker.cmdline)) {
      args += [
        "--cmdline",
        invoker.cmdline,
      ]
    }
    if (defined(invoker.dtb_overlay)) {
      args += [
        "--dtb-overlay",
        "data/dtb_overlay",
      ]
    }
    if (defined(invoker.block_devices)) {
      foreach(block_spec, invoker.block_devices) {
        args += [
          "--block",
          block_spec,
        ]
      }
    }
    if (defined(invoker.cpus)) {
      args += [
        "--cpus",
        invoker.cpus,
      ]
    }
    if (defined(invoker.memory)) {
      args += [
        "--memory",
        invoker.memory,
      ]
    }
    args += [ rebase_path("$guest_config_file") ]
  }

  package(target_name) {
    testonly = defined(invoker.testonly) && invoker.testonly

    deps = [ ":${guest_config_target_name}" ]
    inputs = []
    resources = []

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

    if (defined(invoker.metadata)) {
      metadata = invoker.metadata
    }

    meta = [
      {
        path =
            rebase_path("//src/virtualization/packages/meta/guest_package.cmx")
        dest = "${target_name}.cmx"
      },
    ]

    # Add kernel resource.
    if (defined(invoker.zircon)) {
      kernel = rebase_path(invoker.zircon)
      inputs += [ kernel ]
      resources += [
        {
          path = kernel
          dest = "kernel"
        },
      ]
    }
    if (defined(invoker.linux)) {
      kernel = rebase_path(invoker.linux)
      inputs += [ kernel ]
      resources += [
        {
          path = kernel
          dest = "kernel"
        },
      ]
    }

    # Add ramdisk resource.
    if (defined(invoker.ramdisk)) {
      ramdisk = rebase_path(invoker.ramdisk)
      inputs += [ ramdisk ]
      resources += [
        {
          path = ramdisk
          dest = "ramdisk"
        },
      ]
    }

    # Add DTB overlay resource.
    if (defined(invoker.dtb_overlay)) {
      dtb_overlay = rebase_path(invoker.dtb_overlay)
      inputs += [ dtb_overlay ]
      resources += [
        {
          path = dtb_overlay
          dest = "dtb_overlay"
        },
      ]
    }

    resources += [
      {
        path = rebase_path(guest_config_file)
        dest = "guest.cfg"
      },
    ]

    # Pass-through any additional resources.
    if (defined(invoker.resources)) {
      resources += invoker.resources
    }
  }
}

# Defines a guest prebuilt.
#
# Parameters
#   source (string, required)
#   output (string, required)
template("guest_prebuilt") {
  assert(defined(invoker.source), "")
  assert(defined(invoker.output), "")
  action(target_name) {
    script = "//src/virtualization/packages/check_image.sh"

    # If the input file exists, we want to copy it to the output.
    # Otherwise, we want to generate an empty file.
    #
    # GN has no way to specify an "optional input" -- we can either
    # specify an input (causing GN to error out if the file doesn't
    # exist); or not specify an input (meaning that GN will not rebuild
    # when the input image changes).
    #
    # We work around this by not specifying the input file as
    # a dependency explicitly, but having the "check_image.sh" script
    # out a depfile the first time it is run. This gives the script
    # a chance to run and generate a fake empty image file the first
    # time it runs, and after that, GN will correctly rebuild when
    # required.
    depfile = "${invoker.output}.d"

    args = [
      rebase_path(invoker.source, root_build_dir),
      rebase_path(invoker.output, root_build_dir),
      rebase_path(depfile, root_build_dir),
    ]

    outputs = [ invoker.output ]
  }
}
