# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Rules to generate python packaged applications for Dart

import("../mojo_sdk.gni")

template("dart_package") {
  action(target_name) {
    script = rebase_path("mojo/public/tools/gn/zip.py", ".", mojo_root)

    inputs = invoker.sources

    deps = []
    zip_inputs = []

    if (defined(invoker.deps)) {
      deps += invoker.deps
      foreach(d, invoker.deps) {
        dep_name = get_label_info(d, "name")
        dep_target_out_dir = get_label_info(d, "target_out_dir")
        zip_inputs += [ "$dep_target_out_dir/$dep_name.dartzip" ]
      }
    }

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

    output = "$target_out_dir/$target_name.dartzip"
    outputs = [
      output,
    ]

    rebase_base_dir =
        rebase_path(get_label_info(":$target_name", "dir"), root_build_dir)
    rebase_inputs = rebase_path(inputs, root_build_dir)
    rebase_zip_inputs = rebase_path(zip_inputs, root_build_dir)
    rebase_output = rebase_path(output, root_build_dir)
    args = [
      "--base-dir=$rebase_base_dir",
      "--inputs=$rebase_inputs",
      "--zip-inputs=$rebase_zip_inputs",
      "--output=$rebase_output",
    ]
  }
}

# Use this template to generate a .mojo dart application. One of the source
# files should be named main.dart and contain a main function as the
# entry point. Dependencies of dart_packaged_application targets should be
# either mojom targets (and specified using the mojom_deps variable) or
# dart_package targets.
template("dart_packaged_application") {
  package_name = "${target_name}_package"
  package_analyze_sources = "${target_name}_analyze"
  package_output = "$target_out_dir/$package_name.dartzip"

  if (defined(invoker.output_name)) {
    mojo_output = "$root_out_dir/" + invoker.output_name + ".mojo"
  } else {
    mojo_output = "$root_out_dir/" + target_name + ".mojo"
  }

  action_foreach(package_analyze_sources) {
    sources = invoker.sources

    script = rebase_path("mojo/public/tools/dart_analyze.py", ".", mojo_root)

    args = [
      rebase_path(root_gen_dir),
      rebase_path("$target_gen_dir/{{source_name_part}}.stamp"),
      "{{source}}",
      "--no-hints",
      "--url-mapping=mojo:application,/" +
          rebase_path("mojo/public/dart/application.dart", "/", mojo_root),
      "--url-mapping=mojo:bindings,/" +
          rebase_path("mojo/public/dart/bindings.dart", "/", mojo_root),
      "--url-mapping=mojo:builtin,/" +
          rebase_path("mojo/dart/embedder/builtin.dart", "/", mojo_root),
      "--url-mapping=mojo:core,/" +
          rebase_path("mojo/public/dart/core.dart", "/", mojo_root),
    ]

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

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

    outputs = [
      "$target_gen_dir/{{source_name_part}}.stamp",
    ]
  }

  dart_package(package_name) {
    sources = invoker.sources
    if (defined(invoker.deps)) {
      deps = invoker.deps
    }
    if (defined(invoker.mojom_deps)) {
      mojom_deps = invoker.mojom_deps
    }
    if (defined(invoker.datadeps)) {
      datadeps = invoker.datadeps
    }
  }

  action(target_name) {
    script = rebase_path("mojo/public/tools/prepend.py", ".", mojo_root)

    input = package_output
    inputs = [
      input,
    ]

    output = mojo_output
    outputs = [
      output,
    ]

    deps = [
      # TODO(erg): When dartanalyze runs at an acceptable speed, add
      # ":$package_analyze_sources" as a dependency here and remove the
      # manual group("check") in the toplevel build file.
      ":$package_name",
    ]
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }
    if (defined(invoker.mojom_deps)) {
      deps += invoker.mojom_deps
    }
    if (defined(invoker.datadeps)) {
      datadeps = invoker.datadeps
    }

    line = "#!mojo mojo:dart_content_handler"
    if (is_debug || (defined(invoker.strict) && invoker.strict == true)) {
      line = "#!mojo mojo:dart_content_handler?strict=true"
    }

    rebase_input = rebase_path(input, root_build_dir)
    rebase_output = rebase_path(output, root_build_dir)
    args = [
      "--input=$rebase_input",
      "--output=$rebase_output",
      "--line=$line",
    ]
  }
}
