# Copyright 2019 The Pigweed Authors
#
# 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_overrides/pigweed.gni")

import("$dir_pw_build/input_group.gni")
import("$dir_pw_build/python_action.gni")

declare_args() {
  # Whether or not the current target should build docs.
  pw_docgen_BUILD_DOCS = false

  # Set to enable Google Analytics tracking of generated docs.
  pw_docs_google_analytics_id = ""
}

# Defines a group of documentation files and assets.
#
# Args:
#   sources: Source files for the documentation (.rst or .md).
#   inputs: Additional resource files for the docs, such as images.
#   group_deps: Other pw_doc_group targets on which this group depends.
#   report_deps: Report card targets on which documentation depends.
#   other_deps: Dependencies on any other types of targets.
template("pw_doc_group") {
  assert(defined(invoker.sources), "pw_doc_group requires a list of sources")

  if (defined(invoker.inputs)) {
    _inputs = invoker.inputs
  } else {
    _inputs = []
  }

  _all_deps = []
  if (defined(invoker.group_deps)) {
    _all_deps += invoker.group_deps
  }
  if (defined(invoker.report_deps)) {
    _all_deps += invoker.report_deps
  }
  if (defined(invoker.other_deps)) {
    _all_deps += invoker.other_deps
  }

  # Create a group containing the source and input files so that docs are
  # rebuilt on file modifications.
  pw_input_group(target_name) {
    metadata = {
      pw_doc_sources = rebase_path(invoker.sources, root_build_dir)
      pw_doc_inputs = rebase_path(_inputs, root_build_dir)
    }
    deps = _all_deps
    inputs = invoker.sources + _inputs
  }
}

# Creates a target to build HTML documentation from groups of sources.
#
# Args:
#   deps: List of pw_doc_group targets.
#   sources: Top-level documentation .rst source files.
#   conf: Configuration script (conf.py) for Sphinx.
#   output_directory: Path to directory to which HTML output is rendered.
template("pw_doc_gen") {
  assert(defined(invoker.deps),
         "pw_doc_gen requires doc groups as dependencies")
  assert(defined(invoker.sources) && invoker.sources != [],
         "pw_doc_gen requires a 'sources' list with at least one .rst source")
  assert(defined(invoker.conf),
         "pw_doc_gen requires a 'conf' argument pointing a top-level conf.py")
  assert(defined(invoker.output_directory),
         "pw_doc_gen requires an 'output_directory' argument")

  # Collects all dependency metadata into a single JSON file.
  _metadata_file_target = "${target_name}_metadata"
  generated_file(_metadata_file_target) {
    outputs = [ "$target_gen_dir/$target_name.json" ]
    data_keys = [
      "pw_doc_sources",
      "pw_doc_inputs",
    ]
    output_conversion = "json"
    deps = invoker.deps
  }

  _script_args = [
    "--gn-root",
    rebase_path("//", root_build_dir),
    "--gn-gen-root",
    rebase_path(root_gen_dir, root_build_dir) + "/",
    "--sphinx-build-dir",
    rebase_path("$target_gen_dir/pw_docgen_tree", root_build_dir),
    "--conf",
    rebase_path(invoker.conf, root_build_dir),
    "--out-dir",
    rebase_path(invoker.output_directory, root_build_dir),
  ]

  # Enable Google Analytics if a measurement ID is provided
  if (pw_docs_google_analytics_id != "") {
    _script_args += [
      "--google-analytics-id",
      pw_docs_google_analytics_id,
    ]
  }

  # Metadata JSON file path.
  _script_args += [ "--metadata" ]
  _script_args +=
      rebase_path(get_target_outputs(":$_metadata_file_target"), root_build_dir)

  _script_args += rebase_path(invoker.sources, root_build_dir)

  # Required to set the PYTHONPATH for any automodule/class/function RST
  # directives.
  _python_metadata_deps = [ "$dir_pw_docgen/py" ]
  if (defined(invoker.python_metadata_deps)) {
    _python_metadata_deps += invoker.python_metadata_deps
  }

  if (pw_docgen_BUILD_DOCS) {
    pw_python_action(target_name) {
      script = "$dir_pw_docgen/py/pw_docgen/docgen.py"
      args = _script_args
      deps = [ ":$_metadata_file_target" ]
      python_metadata_deps = _python_metadata_deps
      inputs = [ invoker.conf ]
      inputs += invoker.sources
      stamp = true
    }
  } else {
    group(target_name) {
    }
  }
}
