# Lint as: python3
# pylint: disable=g-direct-third-party-import
# Copyright 2026 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 converting .html/.md(x) docs to valid .mdx files."""

import os
import re
import sys

from absl import app
from absl import flags
import markdownify
from scripts.docs import clr_converter
from scripts.docs import mdx_fixes


FLAGS = flags.FLAGS

flags.DEFINE_string(
    "in_dir",
    None,
    "Absolute path of the input directory (where .html and .md(x) files "
    "should be read from).",
)
flags.DEFINE_string(
    "out_dir",
    None,
    "Absolute path of the output directory (where .mdx files should be"
    " written to).",
)
flags.mark_flag_as_required("in_dir")
flags.mark_flag_as_required("out_dir")


_TEMPLATE_RE = re.compile(r"^\{%.+$\n", re.MULTILINE)
_TAG_RE = re.compile(r"\s?\{:[^}]+\}")
_METADATA_PATTERN = re.compile(
    "^((Project|Book):.+\n)", re.MULTILINE
)
_HTML_COMMENT_RE = re.compile(r"<!--.*?-->", re.DOTALL)
# Flag docs wrap the anchor link inside <code>, which markdownify drops.
# Move the link outside <code> so it survives conversion to MDX definition
# lists.
_CODE_FLAG_LINK_RE = re.compile(
    r'<code(?:\s[^>]*)?><a href="(#[^"]+)">(.*?)</a>(.*?)</code>',
    re.DOTALL,
)
# Definition-list flag terms that should expose a copyable deep-link anchor.
_FLAG_TERM_LINK_RE = re.compile(
    r"^\[`([^`]+)`\]\(#((?:[^)]*-)?flag--[^)]+)\)",
)
_HEADING_TAG_RE = re.compile(
    r"^([^\n]*)<h([1-6])([^>]*)>(.*?)</h\2>",
    re.DOTALL | re.IGNORECASE | re.MULTILINE,
)
_HEADING_ID_ATTR_RE = re.compile(r"""\bid=(["'])([^"']+)\1""")
# See docstrings of _format_table_cell() and ()
# for an explanation.
_TAGS_TO_FLATTEN_RE = re.compile(r"(?:</?(?:pre|code)[^>]*>)+")

# In prose (outside code/pre blocks), these characters must be converted to
# HTML entities so they don't look like JSX or JavaScript blocks to MDX parsers.
_REPLACED_JS_CHARACTERS = {
    "{": "&lcub;",
    "}": "&rcub;",
    "$": "&#36;",
}

_REPLACED_CODE_CHARACTERS = {
    "<": "&lt;",
    ">": "&gt;",
    **_REPLACED_JS_CHARACTERS,
}

_CONFIGURATION_HTML_BAD_LINE = re.compile(
    r"^<p>Use this to distinguish different configurations for the same"
    r" target.+$",
    re.MULTILINE,
)


def _escape_chars(text, replacements):
  """Escapes characters in a string.

  Args:
    text: str; string that needs characters escaped.
    replacements: dict[str, str]; a dictionary mapping characters to escape with
      their replacements.

  Returns:
    The escaped version of `text`.
  """
  for c in replacements.keys():
    text = text.replace(c, replacements[c])
  return text


# Table cells containing these elements cannot be represented as plain markdown
# table cell text. Preserve their inner HTML so MDX renders them correctly.
_COMPLEX_CELL_TAGS = frozenset(["ul", "ol", "table", "pre"])


def _cell_has_complex_content(cell):
  """Returns True if a table cell contains content that needs HTML preservation."""
  return cell.find(list(_COMPLEX_CELL_TAGS)) is not None


def _cell_inner_html(cell):
  """Returns the raw inner HTML of a table cell."""
  return "".join(str(child) for child in cell.children).strip()


def _format_table_cell(cell, content):
  """Formats table cell content as a markdown table cell.

  Markdownify converts elements bottom-up.
  For table cells we discard the already converted tag and instead
  manually "convert" the inner HTML, which can be very complex.

  A better approach would be this:
  For every tag <foo> that can produce multi-line Markdown output:r
  If convert_foo is called for a nested table, it should preserve <foo>
  tags and return the (already converted) content as a single line.
  Otherwise it just delegates to the super class implementation.
  However, this cannot be implemented since parent_tags is a set and not a
  dict or multiset, so we cannot distinguish a simple table from a
  nested table.

  Args:
    cell: The BeautifulSoup table cell element (`td` or `th`).
    content: str; the raw inner HTML content of the table cell.

  Returns:
    The formatted single-line Markdown table cell string.
  """
  colspan = 1
  if "colspan" in cell.attrs and cell["colspan"].isdigit():
    colspan = max(1, min(1000, int(cell["colspan"])))
  # Content = raw HTML, i.e. it can contain tags such as <code> or <pre>
  # with forbidden characters in their values (such as curly braces).
  # Consequently, we need to escape them here.
  return f" {_convert_html_to_single_line_md(content)}{' |' * colspan}"


def _convert_html_to_single_line_md(content):
  """Converts 'bad' tags (<pre>, <code>) and fits the result into a single line.

  These tags are 'bad' since they can contain reserved chars such as curly
  braces,
  which lead to syntax errors if they appear outside of fenced Markdown code
  blocks.

  Args:
    content: str; the raw HTML content to convert.

  Returns:
    A single-line Markdown/HTML string with `<pre>` and `<code>` tags flattened.
  """
  # Convert <pre> and <code> to single fenced code blocks.
  no_bad_tags = _TAGS_TO_FLATTEN_RE.sub("`", content)

  # Escape special characters outside of fenced code blocks.
  parts = no_bad_tags.split("`")
  for i in range(0, len(parts), 2):
    parts[i] = _escape_chars(parts[i], _REPLACED_JS_CHARACTERS)
  escaped = "`".join(parts)

  # Remove line breaks.
  raw_lines = [l.strip() for l in escaped.split("\n")]
  return " ".join([l for l in raw_lines if l])


class AcornSafeMarkdownConverter(markdownify.MarkdownConverter):
  """Custom converter that produces Acorn-parsable MDX output."""

  def convert_td(self, el, text, parent_tags):
    if _cell_has_complex_content(el):
      return _format_table_cell(el, _cell_inner_html(el))
    return super().convert_td(el, text, parent_tags)

  def convert_th(self, el, text, parent_tags):
    if _cell_has_complex_content(el):
      return _format_table_cell(el, _cell_inner_html(el))
    return super().convert_th(el, text, parent_tags)

  def convert_code(self, node, text, parent_tags):
    """Normalize whitespace in inline code before converting.

    Args:
      node: The HTML element being converted.
      text: The text content within the code tag.
      parent_tags: A list of parent tag names.

    Returns:
      The converted markdown string.
    """
    if "pre" not in parent_tags:
      # Multi-line <code> elements in the source HTML cause acorn parse errors
      # when curly braces span line boundaries. Collapsing whitespace first
      # lets the standard backtick conversion handle them on a single line.
      text = " ".join(text.split())

    return super().convert_code(node, text, parent_tags)

  def escape(self, text, parent_tags):
    """Custom escape handling."""
    if not text:
      return text
    escaped = super().escape(text, parent_tags)
    # Unescape underscores that are in the middle of words.
    escaped = re.sub(r"(\w)\\_(\w)", r"\1_\2", escaped)
    # Fenced and inline code blocks are already safe from MDX parsing.
    if "pre" in parent_tags or "code" in parent_tags:
      return escaped
    return _escape_chars(escaped, _REPLACED_CODE_CHARACTERS)


def _convert_directory(root_dir, mdx_dir):
  """Converts all .html and .md(x) files to .mdx files.

  Args:
      root_dir: str; full path of the directory with .html/.md(x) files (input).
      mdx_dir: str; full path of the directory where .mdx files should be
        created (output).
  """
  for curr_dir, _, files in os.walk(root_dir):
    rel = os.path.relpath(curr_dir, start=root_dir)
    dest_dir = os.path.join(mdx_dir, rel)
    os.makedirs(dest_dir, exist_ok=True)

    for fname in files:
      basename, ext = os.path.splitext(fname)
      if ext not in (".html", ".md", ".mdx"):
        continue

      src = os.path.join(curr_dir, fname)
      dest = os.path.join(dest_dir, f"{basename}.mdx")

      _convert_file(src, dest)


def _convert_file(src, dest):
  with open(src, "rt") as f:
    content = f.read()

  with open(dest, "wt") as f:
    f.write(_transform(src, content))


def _transform(path, content):
  """Transforms the content of an HTML or Markdown file into valid MDX."""
  content = _pre_markdown_transforms(content)
  if path.endswith(".html"):
    if os.path.basename(path) == "command-line-reference.html":
      md = clr_converter.convert(content)
    else:
      if path.endswith("configuration.html"):
        fixed_content = _fix_configuration_dot_html(content)
      elif path.endswith("bzl.html"):
        fixed_content = _fix_bzl_dot_html(content)
      else:
        fixed_content = content

      md = _html2md(fixed_content)
  else:
    md = content
  return _post_markdown_transforms(md)


def _fix_configuration_dot_html(content):
  """Fixes malformed HTML in rules/lib/builtins/configurations.html."""

  def fix(m):
    return f"{m.group(0).replace('.', '.</li>')}</ul></p>"

  return _CONFIGURATION_HTML_BAD_LINE.sub(fix, content)


def _fix_bzl_dot_html(content):
  """Fixes malformed HTML link in rules/lib/globals/bzl.html.

  There is only a single instance of this bug, so it doesn't
  make sense to implement a general solution.

  Args:
    content: str; the HTML content to be fixed.
  Returns:
    The fixed HTML content, as string.
  """
  href = "../globals/workspace#register_execution_platforms"
  return content.replace(f'"{href}>', f'"{href}">')


def _html2md(content):
  # HTML content needs a few extra transforms.
  content = _move_flag_links_outside_code(content)
  return AcornSafeMarkdownConverter(heading_style="ATX").convert(content)


def _pre_markdown_transforms(content):
  """Transforms applied to all sources before any markdown conversion.

  Args:
    content: str; content of an HTML or .md file.

  Returns:
    The file with invalid content removed.
  """
  no_tags = _TAG_RE.sub("", content)
  no_comments = _HTML_COMMENT_RE.sub("", no_tags)
  # Remove Project: and Book: lines
  no_metadata = _METADATA_PATTERN.sub("", no_comments, count=2).lstrip()
  no_templates = _TEMPLATE_RE.sub("", no_metadata)
  return _convert_heading_ids_to_mdx_anchors(no_templates)


def _move_flag_links_outside_code(content):
  """Moves in-code flag anchor links outside of <code> tags.

  HtmlUtils.getUsageHtml() renders flags as
  <code><a href="#flag--name">--name</a>...</code>. Markdownify discards links
  nested inside inline code, so restructure the HTML before conversion.

  Args:
    content: str; HTML content before markdown conversion.

  Returns:
    Content with flag links moved outside of <code> tags.
  """
  return _CODE_FLAG_LINK_RE.sub(
      r'<a href="\1"><code>\2\3</code></a>',
      content,
  )


def _convert_heading_ids_to_mdx_anchors(content):
  """Converts HTML headings with id attributes to MDX anchor syntax.

  Example: <h2 id='foo'>Title</h2> -> ## Title {#foo}

  Headings without an id attribute are left unchanged for markdownify.

  Args:
    content: str; HTML content before markdown conversion.

  Returns:
    Content with id-bearing headings converted to MDX anchor syntax.
  """

  def repl(match):
    level = int(match.group(2))
    attrs = match.group(3)
    text = match.group(4).strip()
    id_match = _HEADING_ID_ATTR_RE.search(attrs)
    if not id_match:
      return match.group(0)
    # Hack: do not add anchor if heading has non-empty prefix (e.g. list tag)
    line_prefix = match.group(1).strip()
    heading_id = id_match.group(2)
    anchor = "" if line_prefix else f" {{#{heading_id}}}"
    return f"{'#' * level} {text}{anchor}"

  return _HEADING_TAG_RE.sub(repl, content)


def _post_markdown_transforms(content):
  """Transforms applied to all sources after any markdown conversion.

  Args:
    content: str; content of a converted .mdx file.

  Returns:
    The content as fully valid .mdx.
  """
  return _add_flag_anchor_targets(mdx_fixes.apply(content))


def _add_flag_anchor_targets(content):
  """Inserts explicit anchor targets for copyable per-flag deep links.

  After markdown conversion, flag terms look like
  [`--flag_name`](#flag--flag_name). Mintlify needs an element with a matching
  id attribute for those links (and copied URLs) to resolve.

  Args:
    content: str; MDX content after markdown conversion.

  Returns:
    Content with <a id="..."></a> targets inserted before each flag term.
  """
  seen_anchor_ids = set()
  lines = []
  for line in content.split("\n"):
    match = _FLAG_TERM_LINK_RE.match(line)
    if match:
      anchor_id = match.group(2)
      if anchor_id not in seen_anchor_ids:
        seen_anchor_ids.add(anchor_id)
        lines.append(f'<a id="{anchor_id}"></a>')
        lines.append("")
    lines.append(line)
  return "\n".join(lines)


def _fail(msg):
  print(msg, file=sys.stderr)
  exit(1)


def main(unused_argv):
  if not os.path.isdir(FLAGS.in_dir):
    _fail(f"{FLAGS.in_dir} is not a directory")
  if not os.path.isdir(FLAGS.out_dir):
    _fail(f"{FLAGS.out_dir} is not a directory")

  _convert_directory(FLAGS.in_dir, FLAGS.out_dir)


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