# 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 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()

  return rewriter.rewrite_links(path, content, rel_path, version)


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)
