# Lint as: python3
# pylint: disable=g-direct-third-party-import
# Copyright 2022 The Bazel Authors. All rights reserved.
#
# 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
#
#    http://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.
"""A tool for building the documentation for a Bazel release."""
import os
import shutil
import sys
import tarfile
import tempfile
import zipfile

from absl import app
from absl import flags
from scripts.docs import mdx_fixes
from scripts.docs import rewriter

FLAGS = flags.FLAGS

flags.DEFINE_string("version", None, "Name of the Bazel release.")
flags.DEFINE_string(
    "toc_path",
    None,
    "Path to the _toc.yaml file that contains the table of contents for the"
    " versions menu. Optional.",
)
flags.DEFINE_string(
    "buttons_path",
    None,
    "Path to the _buttons.html file that contains the version indicator."
    " Optional.",
)
flags.DEFINE_string(
    "narrative_docs_path",
    None,
    "Path of the archive (zip or tar) that contains the narrative documentation.",
)
flags.DEFINE_string(
    "reference_docs_path",
    None,
    "Path of the archive (zip or tar) that contains the reference documentation.",
)
flags.DEFINE_string(
    "output_path", None,
    "Location where the zip'ed documentation should be written to.")

flags.mark_flag_as_required("version")
flags.mark_flag_as_required("narrative_docs_path")
flags.mark_flag_as_required("reference_docs_path")
flags.mark_flag_as_required("output_path")

_ARCHIVE_FUNCTIONS = {".tar": tarfile.open, ".zip": zipfile.ZipFile}


def create_docs_tree(
    version, toc_path, buttons_path, narrative_docs_path, reference_docs_path
):
  """Creates a directory tree containing the docs for the Bazel version.

  Args:
    version: Version of this Bazel release.
    toc_path: Absolute path to the _toc.yaml file that lists the most recent
      Bazel versions.
    buttons_path: Absolute path of the _buttons.html file that contains the
      version indicator.
    narrative_docs_path: Absolute path of an archive that contains the narrative
      documentation (can be .zip or .tar).
    reference_docs_path: Absolute path of an archive that contains the reference
      documentation (can be .zip or .tar).

  Returns:
    The absolute paths of the root of the directory tree and of
      the final _toc.yaml file.
  """
  root_dir = tempfile.mkdtemp()

  versions_dir = os.path.join(root_dir, "versions")
  os.makedirs(versions_dir)

  toc_dest_path = ""
  if toc_path:
    toc_dest_path = os.path.join(versions_dir, "_toc.yaml")
    shutil.copyfile(toc_path, toc_dest_path)

  release_dir = os.path.join(versions_dir, version)
  os.makedirs(release_dir)

  try_extract(narrative_docs_path, release_dir)
  try_extract(reference_docs_path, release_dir)

  if buttons_path:
    buttons_dest_path = os.path.join(root_dir, "_buttons.html")
    shutil.copyfile(buttons_path, buttons_dest_path)

  return root_dir, toc_dest_path, release_dir


def try_extract(archive_path, output_dir):
  """Tries to extract the given archive into the given directory.

  This function will raise an error if the archive type is not supported.

  Args:
    archive_path: Absolute path of an archive that should be extracted. Can be
      .tar or .zip.
    output_dir: Absolute path of the directory into which the archive should be
      extracted

  Raises:
    ValueError: If the archive has an unsupported file type.
  """
  _, ext = os.path.splitext(archive_path)
  open_func = _ARCHIVE_FUNCTIONS.get(ext)
  if not open_func:
    raise ValueError(
        "File {}: Invalid file extension '{}'. Allowed: {}".format(
            archive_path, ext, _ARCHIVE_FUNCTIONS.keys.join(", ")
        )
    )

  with open_func(archive_path, "r") as archive:
    archive.extractall(output_dir)


def build_archive(version, root_dir, toc_path, output_path, release_dir):
  """Builds a documentation archive for the given Bazel release.

  This function reads all documentation files from the tree rooted in root_dir,
  fixes all links so that they point at versioned files, then builds a zip
  archive of all files.

  Args:
    version: Version of the Bazel release whose documentation is being built.
    root_dir: Absolute path of the directory that contains the documentation
      tree.
    toc_path: Absolute path of the _toc.yaml file. Can be empty if no toc file
      exists.
    output_path: Absolute path where the archive should be written to.
    release_dir: Absolute path of the root directory for this version.
  """
  with zipfile.ZipFile(output_path, "w") as archive:
    for root, _, files in os.walk(root_dir):
      for f in files:
        src = os.path.join(root, f)
        dest = src[len(root_dir) + 1 :]
        rel_path = os.path.relpath(src, release_dir)

        if src != toc_path and rewriter.can_rewrite(src):
          archive.writestr(dest, get_versioned_content(src, rel_path, version))
        else:
          archive.write(src, dest)


def get_versioned_content(path, rel_path, version):
  """Rewrites links in the given file to point at versioned docs.

  Args:
    path: Absolute path of the file that should be rewritten.
    rel_path: Relative path of the file that should be rewritten.
    version: Version of the Bazel release whose documentation is being built.

  Returns:
    The content of the given file, with rewritten links.
  """
  with open(path, "rt", encoding="utf-8") as f:
    content = f.read()

  # Generated docs are processed by docs2mdx, which already called
  # mdx_fixes.apply().
  fixed_content = content if is_generated(path) else mdx_fixes.apply(content)
  return rewriter.rewrite_links(path, fixed_content, rel_path, version)


def is_generated(path):
  """Returns whether the given file is part of the generated documentation."""
  return (
      "/reference/be/" in path
      or "command-line-reference" in path
      or "/rules/lib/" in path
  )


def main(unused_argv):
  version = FLAGS.version
  output_path = FLAGS.output_path
  root_dir, toc_path, release_dir = create_docs_tree(
      version=version,
      toc_path=FLAGS.toc_path,
      buttons_path=FLAGS.buttons_path,
      narrative_docs_path=FLAGS.narrative_docs_path,
      reference_docs_path=FLAGS.reference_docs_path,
  )

  build_archive(
      version=version,
      root_dir=root_dir,
      toc_path=toc_path,
      output_path=output_path,
      release_dir=release_dir,
  )


if __name__ == "__main__":
  FLAGS(sys.argv)
  app.run(main)
