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

# Given a .cmx file, validates the module facet of it
#
# Parameters
#   cmx (required)
#     This is the .cmx file that wants to be validated.
#
#   deps (optional)
template("cmx_module_validate") {
  module_facet_validation = target_name + "_module_facet"

  # Validate the |fuchsia.module| facet schema.
  validate_json(module_facet_validation) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "public_deps",
                             "testonly",
                             "visibility",
                           ])

    data = invoker.cmx
    schema = "//build/cmx/facets/module_facet_schema.json"
  }
}

# Validates a cmx file
#
# The cmx_validate template will ensure that a given cmx file is conformant to
# the cmx schema, as defined by //src/sys/cmc/schema.json. A stamp file is
# generated to mark that a given cmx file has passed.
#
# Parameters
#
#   data (required)
#     [file] The path to the cmx file that is to be validated
#   extra_schemas (optional)
#     [list of scopes] Paths to extra json schemas to validate the cmx file against.
#     A custom error message can also be provided, to be displayed if the schema fails
#     to validate.
#
#   deps (optional)
#   public_deps (optional)
#   testonly (optional)
#   visibility (optional)
#     Standard GN meaning.
#
# Example of usage:
#
#   cmx_validate(format) {
#     data = meta.path
#   }
template("cmx_validate") {
  compiled_action(target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "sources",
                             "public_deps",
                             "testonly",
                             "visibility",
                           ])

    tool = "//src/sys/cmc"
    tool_output_name = "cmc"

    stamp_file = "$target_gen_dir/$target_name.verified"

    inputs = [ invoker.data ]

    outputs = [ stamp_file ]

    args = [
      "--stamp",
      rebase_path(stamp_file),
      "validate",
      rebase_path(invoker.data),
    ]
    if (defined(invoker.extra_schemas)) {
      foreach(extra_schema, invoker.extra_schemas) {
        schema_path = rebase_path(extra_schema.schema)
        inputs += [ schema_path ]
        args += [ "--extra_schema" ]
        if (defined(extra_schema.error_msg)) {
          args += [ "${schema_path}:${extra_schema.error_msg}" ]
        } else {
          args += [ "${schema_path}" ]
        }
      }
    }
  }
  cmx_module_validate("module_" + target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "testonly",
                             "visibility",
                           ])
    cmx = invoker.data
  }
}

# Compiles a cml file
#
# The cm_compile template will compile a cml file into a cm file. It will
# pretty-print the given cm file if is_debug is set to true.
#
# Parameters
#
#   data (required)
#     [file] The path to the cml file that is to be compiled.
#
#   deps (optional)
#   public_deps (optional)
#   testonly (optional)
#   visibility (optional)
#     Standard GN meaning.
#
# Example of usage:
#
#   cm_compile(format) {
#     data = rebase_path(meta.path)
#   }
template("cm_compile") {
  compiled_action(target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "public_deps",
                             "testonly",
                             "visibility",
                           ])
    tool = "//src/sys/cmc"
    tool_output_name = "cmc"

    compiled_output = "$target_out_dir/$target_name"
    inputs = [ invoker.data ]
    outputs = [ compiled_output ]

    args = [
      "compile",
      "--output",
      rebase_path(compiled_output),
      invoker.data,
    ]

    if (is_debug) {
      args += [ "--pretty" ]
    }
  }
}

# Merges together cmx files
#
# The cmx_merge template will combine the given cmx files into a single cmx
# file.
#
# Parameters
#
#   sources (required)
#     [list of files] A list of cmx files that are to be merged.
#
#   deps (optional)
#   public_deps (optional)
#   testonly (optional)
#   visibility (optional)
#     Standard GN meaning.
#
#   dest (optional)
#     The name the output file in the target out directory. Defaults to the
#     target name.
#
# Example of usage:
#
#   cmx_merge(format) {
#     sources = [
#       rebase_path(meta.path),
#       rebase_path(
#           "//topaz/runtime/dart_runner/meta/aot${product_suffix}_runtime"),
#     ]
#   }
template("cmx_merge") {
  compiled_action(target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "sources",
                             "public_deps",
                             "testonly",
                             "visibility",
                             "dest",
                           ])

    if (!defined(dest)) {
      dest = target_name
    }

    tool = "//src/sys/cmc"
    tool_output_name = "cmc"

    merged_output = "${target_out_dir}/${dest}"
    inputs = invoker.sources
    outputs = [ merged_output ]

    args = [
      "merge",
      "--output",
      rebase_path(merged_output),
    ]

    foreach(source, sources) {
      args += [ rebase_path(source, root_build_dir) ]
    }
  }
}

# Formats a cmx file
#
# The cmx_format template will minify the given cmx file if is_debug is set to
# false, and will pretty-print the given cmx file if is_debug is set to true.
#
# Parameters
#
#   data (required)
#     [file] The path to the cmx file that is to be formatted
#
#   deps (optional)
#   public_deps (optional)
#   testonly (optional)
#   visibility (optional)
#     Standard GN meaning.
#
# Example of usage:
#
#   cmx_format(format) {
#     data = rebase_path(meta.path)
#   }
template("cmx_format") {
  compiled_action(target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "public_deps",
                             "testonly",
                             "visibility",
                           ])

    tool = "//src/sys/cmc"
    tool_output_name = "cmc"

    formatted_output = "$target_out_dir/$target_name"
    inputs = [ invoker.data ]
    outputs = [ formatted_output ]

    args = [
      "format",
      "--output",
      rebase_path(formatted_output),
      invoker.data,
    ]

    if (is_debug) {
      args += [ "--pretty" ]
    }
  }
}
