# Copyright 2018 Google LLC
#
# 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
#
#     https://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/toolchain/embedded.gni")

# Build image, link to an ELF file then convert to plain binary.
template("image_binary") {
  assert(defined(invoker.image_name),
         "image_binary() must specify an \"image_name\" value")

  output_root = ""
  if (defined(invoker.output_path)) {
    output_root += "${invoker.output_path}/"
  }
  output_root += invoker.image_name

  # Link objects together
  executable("${target_name}__elf") {
    forward_variables_from(invoker,
                           [
                             "cflags",
                             "cflags_c",
                             "defines",
                             "deps",
                             "include_dirs",
                             "public_configs",
                             "public_deps",
                             "sources",
                             "testonly",
                           ])
    output_name = "${output_root}.elf"
    inputs = [
      rebase_path("//build/image/image.ld"),
    ]
    ldflags = [
      "-T",
      rebase_path("//build/image/image.ld"),
    ]
    visibility = [ ":${invoker.target_name}" ]
  }

  action(target_name) {
    forward_variables_from(invoker, [ "testonly" ])

    file_root = "${root_out_dir}/${output_root}"
    elf_file = "${file_root}.elf"
    bin_file = "${file_root}.bin"

    script = "//build/image/convert_to_binary.py"
    deps = [
      ":${target_name}__elf",
    ]
    args = [
      "--tool_prefix",
      tool_prefix,
      "--input",
      rebase_path(elf_file),
      "--output",
      rebase_path(bin_file),
    ]
    outputs = [
      bin_file,
    ]
  }
}

# Helper to build a hypervisor image
template("hypervisor") {
  image_binary(target_name) {
    forward_variables_from(invoker,
                           [
                             "cflags",
                             "cflags_c",
                             "defines",
                             "deps",
                             "public_deps",
                             "sources",
                             "testonly",
                           ])
    image_name = target_name
  }
}

# Helper to build a virtual machine kernel
template("vm_kernel") {
  image_binary(target_name) {
    forward_variables_from(invoker,
                           [
                             "cflags",
                             "cflags_c",
                             "defines",
                             "deps",
                             "include_dirs",
                             "public_configs",
                             "public_deps",
                             "sources",
                             "testonly",
                           ])
    output_path = rebase_path(".", root_out_dir, target_out_dir)
    image_name = target_name
  }
}

# Build the initial RAM disk for the hypervisor.
template("initrd") {
  assert(defined(invoker.primary_vm),
         "initrd() must specify a \"primary_vm\" value")

  action(target_name) {
    forward_variables_from(invoker, [ "testonly" ])
    script = "//build/image/generate_initrd.py"

    initrd_base = "${target_out_dir}/${target_name}/initrd"
    initrd_file = "${initrd_base}.img"
    initrd_staging = "${initrd_base}"

    deps = [
      invoker.primary_vm,
    ]

    primary_vm_outputs = get_target_outputs(invoker.primary_vm)
    args = [
      "--primary_vm",
      rebase_path(primary_vm_outputs[0]),
      "--staging",
      rebase_path(initrd_staging),
      "--output",
      rebase_path(initrd_file),
    ]

    # Add the info about the secondary VMs. The information about the VMs is
    # encoded in lists with the following elements:
    #
    #    1. Memory in bytes.
    #    2. Number of cores.
    #    3. File name for the VM image.
    #    4. Build target for the VM.
    if (defined(invoker.secondary_vms)) {
      foreach(vm, invoker.secondary_vms) {
        deps += [ vm[3] ]
        args += [
          "--secondary_vm",
          vm[0],
          vm[1],
          vm[2],
          rebase_path(get_label_info(vm[3], "target_out_dir") + "/" +
                      get_label_info(vm[3], "name") + ".bin"),
        ]
      }
    }

    outputs = [
      initrd_file,
      "${initrd_staging}/vms.txt",
    ]
  }
}
