#!/usr/bin/env python3
# Copyright 2026 WebAssembly Community Group participants
#
# 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.

"""Multi-metric differential test coverage reporter for Binaryen.

Intersects Git or Jujutsu (`jj`) diff hunks with Clang/LLVM source-based code
coverage (`llvm-cov export`) to report Line, Region, Branch, MC/DC, and Function
coverage specifically for the code modified in a change. With -a / --annotate,
also prints the diff annotated with coverage information.

Prints instructions for configuring a coverage reporting build and collecting
coverage information if a coverage build cannot be found automatically.
"""

import argparse
import fnmatch
import glob
import json
import os
import re
import shlex
import shutil
import subprocess
import sys
from dataclasses import dataclass, field

SCRIPT_PATH = os.path.relpath(os.path.abspath(__file__))

REPO_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

CPP_EXTENSIONS = {'.c', '.cpp', '.h', '.inc'}

HUNK_RE = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@')
UNREACHABLE_RE = re.compile(
    r'\b(WASM_UNREACHABLE|WASM_BUILTIN_UNREACHABLE|__builtin_unreachable)\b'
    r'|LCOV_EXCL_LINE|GCOVR_EXCL_LINE|COV_EXCL_LINE',
)
DEFAULT_LABEL_RE = re.compile(r'^\s*default\s*:\s*(//.*|/\*.*\*/)?$')
CLOSING_BRACE_RE = re.compile(r'^\s*\}\s*(//.*|/\*.*\*/)?$')

# CounterMappingRegion::RegionKind values in llvm-cov JSON export.
REGION_KIND_CODE = 0


@dataclass
class Segment:
    line: int
    col: int
    count: int
    has_count: bool
    is_region_entry: bool
    is_gap_region: bool


@dataclass
class LineStat:
    line: int
    mapped: bool
    count: int


@dataclass
class CodeRegion:
    line_start: int
    col_start: int
    line_end: int
    col_end: int
    count: int


@dataclass
class BranchRecord:
    line_start: int
    col_start: int
    line_end: int
    col_end: int
    true_count: int
    false_count: int


@dataclass
class MCDCRecord:
    line_start: int
    col_start: int
    line_end: int
    col_end: int
    conditions: list[bool]


@dataclass
class FunctionSpan:
    name: str
    demangled_name: str
    line_start: int
    line_end: int
    count: int


@dataclass
class MetricCounts:
    covered: int = 0
    total: int = 0

    def add(self, covered: int, total: int):
        self.covered += covered
        self.total += total

    @property
    def percent(self) -> float | None:
        if self.total == 0:
            return None
        return (self.covered * 100.0) / self.total

    def format_summary(self) -> str:
        if self.total == 0:
            return 'N/A (0 in diff)'
        return f'{self.covered} / {self.total} ({self.percent:.1f}%)'


@dataclass
class FileDiffCoverage:
    rel_path: str
    abs_path: str
    diff_lines: list[int]
    hunks: list[tuple[int, int]]
    lines: MetricCounts = field(default_factory=MetricCounts)
    regions: MetricCounts = field(default_factory=MetricCounts)
    branches: MetricCounts = field(default_factory=MetricCounts)
    mcdc: MetricCounts = field(default_factory=MetricCounts)
    functions: MetricCounts = field(default_factory=MetricCounts)
    non_executable_diff_lines: int = 0
    excluded_unreachable_lines: int = 0
    line_stats: dict[int, LineStat] = field(default_factory=dict)
    uncovered_functions: list[FunctionSpan] = field(default_factory=list)
    uncovered_lines: list[int] = field(default_factory=list)
    uncovered_subregions: list[CodeRegion] = field(default_factory=list)
    uncovered_branches: list[BranchRecord] = field(default_factory=list)
    uncovered_mcdc: list[MCDCRecord] = field(default_factory=list)
    in_coverage_map: bool = True


def find_llvm_tool(tool_name: str, explicit_path: str | None = None) -> str | None:
    if explicit_path:
        return explicit_path if shutil.which(explicit_path) or os.path.isfile(explicit_path) else None
    llvm_version = os.environ.get('LLVM_VERSION')
    if llvm_version:
        found = shutil.which(f'{tool_name}-{llvm_version}')
        if found:
            return found
    found = shutil.which(tool_name)
    if found:
        return found
    # Search PATH for versioned binaries (e.g. llvm-cov-22) and pick the newest.
    pattern = re.compile(rf'^{re.escape(tool_name)}-(\d+)$')
    versioned: list[tuple[int, str]] = []
    for path_dir in os.environ.get('PATH', '').split(os.pathsep):
        if not path_dir or not os.path.isdir(path_dir):
            continue
        try:
            for entry in os.listdir(path_dir):
                m = pattern.match(entry)
                if m:
                    full = os.path.join(path_dir, entry)
                    if os.path.isfile(full) and os.access(full, os.X_OK):
                        versioned.append((int(m.group(1)), full))
        except OSError:
            continue
    if versioned:
        versioned.sort(key=lambda item: item[0], reverse=True)
        return versioned[0][1]
    return None


def parse_cmake_cache(cache_path: str) -> dict[str, str]:
    entries: dict[str, str] = {}
    if not os.path.isfile(cache_path):
        return entries
    with open(cache_path, errors='replace') as f:
        for raw_line in f:
            line = raw_line.strip()
            if not line or line.startswith(('#', '//')):
                continue
            if ':' in line and '=' in line:
                key_type, val = line.split('=', 1)
                key = key_type.split(':', 1)[0]
                entries[key] = val
    return entries


def check_build_dir_coverage_config(build_dir: str) -> tuple[bool, str, dict[str, str]]:
    """Return (is_valid, reason, cmake_cache_dict)."""
    cache_path = os.path.join(build_dir, 'CMakeCache.txt')
    if not os.path.isfile(cache_path):
        return False, f"No CMakeCache.txt found in '{build_dir}'.", {}

    cache = parse_cmake_cache(cache_path)
    cxx = cache.get('CMAKE_CXX_COMPILER', '')
    build_type = cache.get('CMAKE_BUILD_TYPE', 'Release').upper()
    cxx_flags = ' '.join([
        cache.get('CMAKE_CXX_FLAGS', ''),
        cache.get(f'CMAKE_CXX_FLAGS_{build_type}', ''),
    ])
    c_flags = ' '.join([
        cache.get('CMAKE_C_FLAGS', ''),
        cache.get(f'CMAKE_C_FLAGS_{build_type}', ''),
    ])

    cxx_base = os.path.basename(cxx)
    if 'clang' not in cxx_base:
        return (
            False,
            f"Build in '{build_dir}' uses compiler '{cxx or 'unknown'}' instead of Clang "
            "(Clang is required for source-based coverage mapping).",
            cache,
        )

    required_flags = ('-fprofile-instr-generate', '-fcoverage-mapping')
    missing_cxx = [fl for fl in required_flags if fl not in cxx_flags]
    missing_c = [fl for fl in required_flags if fl not in c_flags]
    if missing_cxx or missing_c:
        return (
            False,
            f"Build in '{build_dir}' is missing coverage flags "
            f"({', '.join(required_flags)}) in CMAKE_C_FLAGS / CMAKE_CXX_FLAGS.",
            cache,
        )

    return True, 'OK', cache


def discover_build_dir(explicit_dir: str | None) -> tuple[str, bool, str, dict[str, str]]:
    """Find a coverage-configured build directory or report why candidates failed."""
    if explicit_dir:
        abs_dir = os.path.abspath(explicit_dir)
        ok, reason, cache = check_build_dir_coverage_config(abs_dir)
        return abs_dir, ok, reason, cache

    env_dir = os.environ.get('BINARYEN_BUILD_DIR')
    if env_dir:
        abs_dir = os.path.abspath(env_dir)
        ok, reason, cache = check_build_dir_coverage_config(abs_dir)
        return abs_dir, ok, reason, cache

    candidates = [
        os.path.join(REPO_ROOT, 'out', 'cov'),
        os.path.join(REPO_ROOT, 'build', 'cov'),
        os.path.join(REPO_ROOT, 'cov'),
        REPO_ROOT,
        os.path.join(REPO_ROOT, 'out', 'debug'),
        os.path.join(REPO_ROOT, 'build', 'debug'),
        os.path.join(REPO_ROOT, 'debug'),
        os.path.join(REPO_ROOT, 'out'),
        os.path.join(REPO_ROOT, 'build'),
    ]

    first_existing = None
    for cand in candidates:
        ok, reason, cache = check_build_dir_coverage_config(cand)
        if ok:
            return cand, True, reason, cache
        if first_existing is None and os.path.isfile(os.path.join(cand, 'CMakeCache.txt')):
            first_existing = (cand, False, reason, cache)

    if first_existing:
        return first_existing

    default_cov_dir = os.path.join(REPO_ROOT, 'out', 'cov')
    return default_cov_dir, False, f"No coverage build directory found (checked '{default_cov_dir}' and repo root).", {}


def print_setup_instructions(reason: str, suggested_build_dir: str = 'out/cov'):
    rel_build = os.path.relpath(os.path.abspath(suggested_build_dir), REPO_ROOT)
    if rel_build == '.':
        rel_build = 'out/cov'
    print(f'Error: Build is not configured for coverage reporting.\n  Reason: {reason}\n', file=sys.stderr)
    print(
        f"""If you already have a coverage build directory, specify it with:
  -B <dir> / --build-dir <dir>  (or set BINARYEN_BUILD_DIR=<dir>)

To configure a new Clang coverage build:

  1. Configure CMake with Clang source-based coverage flags (e.g. in '{rel_build}'):
     cmake -S . -B {rel_build} -G Ninja \\
       -DCMAKE_BUILD_TYPE=Debug \\
       -DCMAKE_C_COMPILER=clang \\
       -DCMAKE_CXX_COMPILER=clang++ \\
       -DCMAKE_C_FLAGS="-fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc" \\
       -DCMAKE_CXX_FLAGS="-fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc"

  2. Build the targets exercised by your tests (e.g. wasm-opt, binaryen-unittests):
     ninja -C {rel_build} wasm-opt binaryen-unittests

  3. Run this tool with your test(s) to collect profiles and report diff coverage in one step:
     {SCRIPT_PATH} -B {rel_build} --lit test/lit/passes/<your-test>.wast
     {SCRIPT_PATH} -B {rel_build} --gtest "*YourTest*"
     {SCRIPT_PATH} -B {rel_build} --run "{rel_build}/bin/wasm-opt ..."
""",
        file=sys.stderr,
    )


def print_missing_profile_instructions(build_dir: str):
    rel_build = os.path.relpath(build_dir, REPO_ROOT)
    bin_prefix = f'{rel_build}/bin' if rel_build != '.' else './bin'
    b_flag = f'-B {rel_build} ' if rel_build not in {'.', 'out/cov'} else ''
    print(
        f"Error: No coverage profile data (.profraw or .profdata) found in '{rel_build}'.\n",
        file=sys.stderr,
    )
    print(
        f"""Run tests through coverage-diff.py to automatically generate and merge profiles:

  # Run specific lit test(s):
  {SCRIPT_PATH} {b_flag}--lit test/lit/passes/<your-test>.wast

  # Run GTest unit tests (all or filtered):
  {SCRIPT_PATH} {b_flag}--gtest "*YourFilter*"

  # Run an arbitrary command:
  {SCRIPT_PATH} {b_flag}--run "{bin_prefix}/wasm-opt ..."

Or run tests manually with LLVM_PROFILE_FILE set, then re-run coverage-diff.py:
  LLVM_PROFILE_FILE="$(pwd)/{rel_build}/coverage/profraw/%8m.profraw" {bin_prefix}/binaryen-lit test/lit/...
  {SCRIPT_PATH} {b_flag.rstrip()}
""",
        file=sys.stderr,
    )


def find_object_file_for_source(build_dir: str, rel_path: str) -> str | None:
    """Locate the compiled .o file for a C/C++ source file in build_dir."""
    if rel_path.endswith(('.h', '.inc')):
        return None
    # 1. Standard libbinaryen object path: CMakeFiles/binaryen.dir/<rel_path>.o
    cand = os.path.join(build_dir, 'CMakeFiles', 'binaryen.dir', f'{rel_path}.o')
    if os.path.isfile(cand):
        return cand
    # 2. Subdirectory target object path: <dir>/CMakeFiles/*.dir/<basename>.o
    rel_dir = os.path.dirname(rel_path)
    base_name = os.path.basename(rel_path)
    matches = glob.glob(os.path.join(build_dir, rel_dir, 'CMakeFiles', '*.dir', f'{base_name}.o'))
    if not matches:
        matches = glob.glob(
            os.path.join(build_dir, 'src', 'tools', 'CMakeFiles', '*.dir', '**', f'{base_name}.o'),
            recursive=True,
        )
    return matches[0] if matches else None


def find_coverage_objects(
    build_dir: str,
    explicit_objects: list[str] | None,
    diff_rel_paths: list[str],
    used_gtest: bool,
) -> list[str]:
    if explicit_objects:
        return [os.path.abspath(obj) for obj in explicit_objects]

    # Fast path: if all modified files in the diff are .c/.cpp compilation units
    # with corresponding .o files in build_dir, pass those .o files directly to
    # llvm-cov export (~0.15s) instead of parsing all 300MB+ of libbinaryen.so (~12s).
    obj_files: list[str] = []
    all_have_obj = bool(diff_rel_paths)
    for rel_path in diff_rel_paths:
        obj_file = find_object_file_for_source(build_dir, rel_path)
        if obj_file:
            obj_files.append(obj_file)
        else:
            all_have_obj = False
            break
    if all_have_obj and obj_files:
        return obj_files

    objects: list[str] = []
    lib_dir = os.path.join(build_dir, 'lib')
    for lib_name in ('libbinaryen.so', 'libbinaryen.dylib'):
        lib_path = os.path.join(lib_dir, lib_name)
        if os.path.isfile(lib_path):
            objects.append(lib_path)

    bin_dir = os.path.join(build_dir, 'bin')
    needed_bins: set[str] = set()

    # If static build (no shared libbinaryen), we need at least wasm-opt / binaryen-unittests.
    if not objects:
        needed_bins.update(['wasm-opt', 'binaryen-unittests'])

    if used_gtest:
        needed_bins.add('binaryen-unittests')

    for rel_path in diff_rel_paths:
        parts = rel_path.replace('\\', '/').split('/')
        if len(parts) >= 3 and parts[0] == 'src' and parts[1] == 'tools':
            tool_entry = parts[2]
            if os.path.splitext(tool_entry)[1]:
                needed_bins.add(os.path.splitext(tool_entry)[0])
            else:
                needed_bins.add(tool_entry)
        elif len(parts) >= 2 and parts[0] == 'test' and parts[1] == 'gtest':
            needed_bins.add('binaryen-unittests')
        if rel_path.endswith(('.h', '.inc')):
            # Header changes might only be instantiated inside unit tests or tools.
            needed_bins.update(['wasm-opt', 'binaryen-unittests'])

    for bin_name in sorted(needed_bins):
        bin_path = os.path.join(bin_dir, bin_name)
        if os.path.isfile(bin_path) and os.access(bin_path, os.X_OK):
            objects.append(bin_path)

    # Fallback: if still empty, look for any executable in bin/
    if not objects and os.path.isdir(bin_dir):
        for entry in sorted(os.listdir(bin_dir)):
            if entry == 'binaryen-lit':
                continue
            full = os.path.join(bin_dir, entry)
            if os.path.isfile(full) and os.access(full, os.X_OK):
                objects.append(full)
                break

    return objects


def remove_file_quietly(path: str):
    try:
        os.remove(path)
    except OSError:
        pass


def clear_coverage_profiles(build_dir: str) -> int:
    """Remove all .profraw and .profdata files in build_dir and return count removed."""
    cov_dir = os.path.join(build_dir, 'coverage')
    patterns = [
        os.path.join(cov_dir, 'profraw', '*.profraw'),
        os.path.join(cov_dir, '*.profraw'),
        os.path.join(cov_dir, '*.profdata'),
        os.path.join(build_dir, '*.profraw'),
        os.path.join(build_dir, 'default.profdata'),
        os.path.join(build_dir, 'out', 'test', '**', '*.profraw'),
        os.path.join(REPO_ROOT, '*.profraw'),
    ]
    removed = 0
    seen: set[str] = set()
    for pat in patterns:
        for path in glob.glob(pat, recursive=True):
            if path not in seen and os.path.isfile(path):
                seen.add(path)
                try:
                    os.remove(path)
                    removed += 1
                except OSError:
                    pass
    return removed


def run_test_commands(
    build_dir: str,
    lit_tests: list[str] | None,
    gtest_filter: str | None,
    custom_cmds: list[str] | None,
    append_profiles: bool,
) -> tuple[str, list[str]]:
    """Execute requested tests with LLVM_PROFILE_FILE set and return profraw dir & list."""
    profraw_dir = os.path.join(build_dir, 'coverage', 'profraw')
    os.makedirs(profraw_dir, exist_ok=True)

    if not append_profiles:
        clear_coverage_profiles(build_dir)

    env = os.environ.copy()
    env['LLVM_PROFILE_FILE'] = os.path.join(profraw_dir, '%8m.profraw')
    bin_dir = os.path.join(build_dir, 'bin')
    env['PATH'] = f"{bin_dir}{os.pathsep}{env.get('PATH', '')}"

    commands: list[list[str] | str] = []
    if lit_tests:
        lit_script = os.path.join(bin_dir, 'binaryen-lit')
        if not os.path.isfile(lit_script):
            rel_build = os.path.relpath(build_dir, REPO_ROOT)
            print(
                f"Error: '{lit_script}' not found. Configure and build '{rel_build}' first.",
                file=sys.stderr,
            )
            sys.exit(2)
        commands.append([sys.executable, lit_script, '-vv', *lit_tests])

    if gtest_filter is not None:
        gtest_bin = os.path.join(bin_dir, 'binaryen-unittests')
        if not os.path.isfile(gtest_bin):
            rel_build = os.path.relpath(build_dir, REPO_ROOT)
            print(
                f"Error: '{gtest_bin}' not found. Build it with: ninja -C {rel_build} binaryen-unittests",
                file=sys.stderr,
            )
            sys.exit(2)
        cmd = [gtest_bin]
        if gtest_filter and gtest_filter != '*':
            cmd.append(f'--gtest_filter={gtest_filter}')
        commands.append(cmd)

    if custom_cmds:
        commands.extend(custom_cmds)

    for cmd in commands:
        if isinstance(cmd, list):
            display = shlex.join(cmd)
            res = subprocess.run(cmd, cwd=REPO_ROOT, env=env)
        else:
            display = cmd
            res = subprocess.run(cmd, cwd=REPO_ROOT, env=env, shell=True)
        if res.returncode != 0:
            print(f'Error: Test command failed (exit code {res.returncode}): {display}', file=sys.stderr)
            sys.exit(res.returncode)

    profraw_files = sorted(glob.glob(os.path.join(profraw_dir, '*.profraw')))
    return profraw_dir, profraw_files


def resolve_profdata(
    build_dir: str,
    llvm_profdata: str,
    explicit_profdata: str | None,
    profraw_files: list[str] | None,
    objects: list[str] | None = None,
) -> str | None:
    if explicit_profdata:
        return os.path.abspath(explicit_profdata) if os.path.isfile(explicit_profdata) else None

    cov_dir = os.path.join(build_dir, 'coverage')
    profdata_path = os.path.join(cov_dir, 'coverage.profdata')
    newest_obj_mtime = max(
        (os.path.getmtime(o) for o in (objects or []) if os.path.isfile(o)),
        default=0.0,
    )

    if profraw_files is None:
        # Search standard locations for existing .profraw files.
        search_patterns = [
            os.path.join(cov_dir, 'profraw', '*.profraw'),
            os.path.join(cov_dir, '*.profraw'),
            os.path.join(build_dir, '*.profraw'),
            os.path.join(build_dir, 'out', 'test', '**', '*.profraw'),
            os.path.join(REPO_ROOT, '*.profraw'),
        ]
        found: list[str] = []
        for pat in search_patterns:
            found.extend(glob.glob(pat, recursive=True))
        profraw_files = sorted(set(found))

    # Automatically discard any .profraw files recorded before the target objects were rebuilt.
    if profraw_files and newest_obj_mtime > 0:
        fresh_profraw: list[str] = []
        for p in profraw_files:
            if os.path.getmtime(p) < newest_obj_mtime:
                remove_file_quietly(p)
            else:
                fresh_profraw.append(p)
        if len(fresh_profraw) != len(profraw_files):
            remove_file_quietly(profdata_path)
        profraw_files = fresh_profraw

    if profraw_files:
        os.makedirs(cov_dir, exist_ok=True)
        need_merge = not os.path.isfile(profdata_path)
        if not need_merge:
            profdata_mtime = os.path.getmtime(profdata_path)
            need_merge = any(os.path.getmtime(p) > profdata_mtime for p in profraw_files)
        if need_merge:
            cmd = [llvm_profdata, 'merge', '-sparse', *profraw_files, '-o', profdata_path]
            res = subprocess.run(cmd, capture_output=True, text=True)
            if res.returncode != 0:
                print(f'Error merging profile data with {llvm_profdata}:\n{res.stderr}', file=sys.stderr)
                sys.exit(2)
        return profdata_path

    if os.path.isfile(profdata_path):
        if newest_obj_mtime > 0 and os.path.getmtime(profdata_path) < newest_obj_mtime:
            remove_file_quietly(profdata_path)
        else:
            return profdata_path
    root_profdata = os.path.join(build_dir, 'default.profdata')
    if os.path.isfile(root_profdata):
        if newest_obj_mtime > 0 and os.path.getmtime(root_profdata) < newest_obj_mtime:
            remove_file_quietly(root_profdata)
        else:
            return root_profdata
    return None


def detect_vcs(explicit_vcs: str | None = None) -> str:
    if explicit_vcs and explicit_vcs != 'auto':
        return explicit_vcs
    cur = os.path.abspath(REPO_ROOT)
    while True:
        if os.path.isdir(os.path.join(cur, '.jj')) and shutil.which('jj'):
            return 'jj'
        if os.path.exists(os.path.join(cur, '.git')):
            return 'git'
        parent = os.path.dirname(cur)
        if parent == cur:
            break
        cur = parent
    return 'jj' if shutil.which('jj') and not shutil.which('git') else 'git'


def matches_file_patterns(rel_path: str, file_patterns: list[str] | None) -> bool:
    if not file_patterns:
        return True
    rel_norm = rel_path.replace('\\', '/')
    base_name = os.path.basename(rel_norm)
    target_real = os.path.realpath(os.path.join(REPO_ROOT, rel_norm))
    for raw_pat in file_patterns:
        pat = raw_pat.replace('\\', '/')
        while pat.startswith('./'):
            pat = pat[2:]
        if pat in {rel_norm, base_name}:
            return True
        if fnmatch.fnmatch(rel_norm, pat) or fnmatch.fnmatch(base_name, pat):
            return True
        if not any(ch in raw_pat for ch in '*?[') and os.path.realpath(raw_pat) == target_real:
            return True
    return False


def parse_unified_diff(
    diff_stdout: str,
    file_patterns: list[str] | None = None,
) -> dict[str, tuple[list[int], list[tuple[int, int]]]]:
    file_diffs: dict[str, tuple[set[int], list[tuple[int, int]]]] = {}
    current_file: str | None = None

    for raw_line in diff_stdout.splitlines():
        if raw_line.startswith('diff --git '):
            current_file = None
        elif raw_line.startswith('+++ b/'):
            rel_path = raw_line[6:].strip()
            ext = os.path.splitext(rel_path)[1]
            abs_path = os.path.join(REPO_ROOT, rel_path)
            if (
                ext in CPP_EXTENSIONS
                and os.path.isfile(abs_path)
                and not rel_path.startswith('third_party/')
                and matches_file_patterns(rel_path, file_patterns)
            ):
                current_file = rel_path
                if current_file not in file_diffs:
                    file_diffs[current_file] = (set(), [])
            else:
                current_file = None
        elif raw_line.startswith('+++ /dev/null'):
            current_file = None
        elif current_file and raw_line.startswith('@@ '):
            m = HUNK_RE.match(raw_line)
            if m:
                start_line = int(m.group(1))
                count = int(m.group(2)) if m.group(2) is not None else 1
                if count > 0:
                    lines_set, hunks = file_diffs[current_file]
                    lines_set.update(range(start_line, start_line + count))
                    hunks.append((start_line, count))

    return {
        rel: (sorted(lines_set), hunks)
        for rel, (lines_set, hunks) in sorted(file_diffs.items())
        if lines_set
    }


def get_jj_diff_output(
    base_ref: str | None,
    revisions: str | None,
    staged_only: bool,
) -> tuple[str, str]:
    if staged_only:
        print(
            'Error: --staged is only supported with Git (Jujutsu has no staging area; use -r @ or --base @-).',
            file=sys.stderr,
        )
        sys.exit(2)
    if not shutil.which('jj'):
        print("Error: 'jj' executable not found in PATH.", file=sys.stderr)
        sys.exit(2)

    jj_prefix = ['jj', '--no-pager', '--color=never']
    if revisions:
        diff_cmd = [*jj_prefix, 'diff', '--git', '--context=0', f'--revisions={revisions}']
        desc = f'jj revisions {revisions}'
    elif base_ref:
        diff_cmd = [*jj_prefix, 'diff', '--git', '--context=0', f'--from={base_ref}', '--to=@']
        desc = f'changes vs {base_ref}'
    else:
        mb_res = subprocess.run(
            [*jj_prefix, 'log', '--no-graph', '-r', 'latest(heads(::(trunk() ~ root()) & ::@))', '-T', 'commit_id.short(10)'],
            cwd=REPO_ROOT,
            capture_output=True,
            text=True,
        )
        base_commit = mb_res.stdout.strip().splitlines()[0].strip() if mb_res.returncode == 0 and mb_res.stdout.strip() else ''
        if base_commit:
            rev_res = subprocess.run(
                [*jj_prefix, 'log', '--no-graph', '-r', '(trunk() ~ root())..@', '-T', 'change_id.short(8) ++ "\\n"'],
                cwd=REPO_ROOT,
                capture_output=True,
                text=True,
            )
            if rev_res.returncode == 0 and rev_res.stdout.strip():
                diff_cmd = [*jj_prefix, 'diff', '--git', '--context=0', '--revisions=(trunk() ~ root())..@']
            else:
                diff_cmd = [*jj_prefix, 'diff', '--git', '--context=0', f'--from={base_commit}', '--to=@']
            desc = f'branch changes vs trunk() ({base_commit})'
        else:
            wc_res = subprocess.run(
                [*jj_prefix, 'log', '--no-graph', '-r', '@ & ~empty()', '-T', 'change_id.short(8)'],
                cwd=REPO_ROOT,
                capture_output=True,
                text=True,
            )
            if wc_res.returncode == 0 and wc_res.stdout.strip():
                diff_cmd = [*jj_prefix, 'diff', '--git', '--context=0', '--revisions=@']
                desc = 'working-copy changes (@)'
            else:
                diff_cmd = [*jj_prefix, 'diff', '--git', '--context=0', '--revisions=@-']
                desc = 'parent commit changes (@-)'

    res = subprocess.run(diff_cmd, cwd=REPO_ROOT, capture_output=True, text=True)
    if res.returncode != 0:
        print(f'Error running jj diff:\n{res.stderr}', file=sys.stderr)
        sys.exit(2)
    return desc, res.stdout


def get_git_diff_output(
    base_ref: str | None,
    revisions: str | None,
    staged_only: bool,
) -> tuple[str, str]:
    if staged_only:
        diff_cmd = ['git', 'diff', '--cached', '-U0', '--no-color']
        desc = 'staged changes (git diff --cached)'
    elif revisions:
        if '..' in revisions:
            diff_cmd = ['git', 'diff', '-U0', '--no-color', '--end-of-options', revisions]
        else:
            diff_cmd = ['git', 'diff', '-U0', '--no-color', '--end-of-options', f'{revisions}~1', revisions]
        desc = f'git revisions {revisions}'
    elif base_ref:
        if base_ref.startswith('-'):
            print(f"Error: Invalid base ref '{base_ref}'.", file=sys.stderr)
            sys.exit(2)
        diff_cmd = ['git', 'diff', '-U0', '--no-color', base_ref]
        desc = f'changes vs {base_ref}'
    else:
        # Check if there are uncommitted C/C++ changes against HEAD first.
        status_res = subprocess.run(
            ['git', 'diff', '--name-only', 'HEAD'],
            cwd=REPO_ROOT,
            capture_output=True,
            text=True,
        )
        has_uncommitted_cpp = any(
            os.path.splitext(p.strip())[1] in CPP_EXTENSIONS
            for p in status_res.stdout.splitlines()
            if p.strip()
        )
        if has_uncommitted_cpp:
            diff_cmd = ['git', 'diff', '-U0', '--no-color', 'HEAD']
            desc = 'uncommitted changes vs HEAD'
        else:
            # Fall back to merge-base with upstream or origin/main.
            upstream = '@{upstream}'
            mb_res = subprocess.run(
                ['git', 'merge-base', upstream, 'HEAD'],
                cwd=REPO_ROOT,
                capture_output=True,
                text=True,
            )
            if mb_res.returncode != 0:
                upstream = 'origin/main'
                mb_res = subprocess.run(
                    ['git', 'merge-base', upstream, 'HEAD'],
                    cwd=REPO_ROOT,
                    capture_output=True,
                    text=True,
                )
            if mb_res.returncode == 0 and mb_res.stdout.strip():
                merge_base = mb_res.stdout.strip()
                diff_cmd = ['git', 'diff', '-U0', '--no-color', merge_base]
                desc = f'branch changes vs {upstream} ({merge_base[:10]})'
            else:
                diff_cmd = ['git', 'diff', '-U0', '--no-color', 'HEAD~1']
                desc = 'changes vs HEAD~1'

    res = subprocess.run(diff_cmd, cwd=REPO_ROOT, capture_output=True, text=True)
    if res.returncode != 0:
        print(f'Error running git diff:\n{res.stderr}', file=sys.stderr)
        sys.exit(2)
    return desc, res.stdout


def get_diff_lines(
    vcs: str,
    base_ref: str | None,
    revisions: str | None,
    staged_only: bool,
    file_patterns: list[str] | None = None,
) -> tuple[str, dict[str, tuple[list[int], list[tuple[int, int]]]]]:
    """Return (diff_description, {rel_path: (sorted_lines, [(start, count), ...])})."""
    if vcs == 'jj':
        desc, stdout = get_jj_diff_output(base_ref, revisions, staged_only)
    else:
        desc, stdout = get_git_diff_output(base_ref, revisions, staged_only)
    if file_patterns:
        desc = f"{desc} [files: {', '.join(file_patterns)}]"
    return desc, parse_unified_diff(stdout, file_patterns)


def compute_line_stats(raw_segments: list[list]) -> dict[int, LineStat]:
    """Replicate llvm::coverage::LineCoverageIterator & LineCoverageStats."""
    if not raw_segments:
        return {}

    segments = [
        Segment(
            line=int(s[0]),
            col=int(s[1]),
            count=int(s[2]),
            has_count=bool(s[3]),
            is_region_entry=bool(s[4]),
            is_gap_region=bool(s[5]),
        )
        for s in raw_segments
    ]

    max_line = segments[-1].line
    seg_idx = 0
    num_segs = len(segments)
    wrapped_seg: Segment | None = None
    line_segs: list[Segment] = []
    stats: dict[int, LineStat] = {}

    def is_start_of_region(seg: Segment) -> bool:
        return not seg.is_gap_region and seg.has_count and seg.is_region_entry

    for line in range(1, max_line + 1):
        if seg_idx >= num_segs:
            break
        if line_segs:
            wrapped_seg = line_segs[-1]
        line_segs = []
        while seg_idx < num_segs and segments[seg_idx].line == line:
            line_segs.append(segments[seg_idx])
            seg_idx += 1

        min_region_count = sum(1 for s in line_segs if is_start_of_region(s))
        start_of_skipped = bool(line_segs) and not line_segs[0].has_count and line_segs[0].is_region_entry

        mapped = not start_of_skipped and (
            (wrapped_seg is not None and wrapped_seg.has_count) or (min_region_count > 0)
        )
        if not mapped:
            mapped = any(s.is_region_entry and s.has_count for s in line_segs)

        if not mapped:
            stats[line] = LineStat(line=line, mapped=False, count=0)
            continue

        exec_count = wrapped_seg.count if wrapped_seg is not None else 0
        if min_region_count > 0:
            for s in line_segs:
                if is_start_of_region(s):
                    exec_count = max(exec_count, s.count)

        stats[line] = LineStat(line=line, mapped=True, count=exec_count)

    return stats


def demangle_names(names: list[str]) -> dict[str, str]:
    if not names:
        return {}
    demangler = find_llvm_tool('llvm-cxxfilt') or shutil.which('c++filt')
    if not demangler:
        return {n: n for n in names}
    # Strip leading source filename prefix if present (e.g. "File.cpp:_Z...")
    stripped = [n.split(':', 1)[-1] if ':' in n and n.split(':', 1)[0].endswith(('.cpp', '.c', '.h')) else n for n in names]
    res = subprocess.run(
        [demangler],
        input='\n'.join(stripped),
        capture_output=True,
        text=True,
    )
    if res.returncode != 0:
        return {n: n for n in names}
    out_lines = res.stdout.splitlines()
    if len(out_lines) != len(names):
        return {n: n for n in names}
    return dict(zip(names, [line.strip() for line in out_lines], strict=True))


def find_unreachable_lines(source_lines: list[str]) -> set[int]:
    """Identify 1-indexed lines with WASM_UNREACHABLE or exclusion markers."""
    unreachable: set[int] = set()
    for idx, text in enumerate(source_lines):
        line_no = idx + 1
        if UNREACHABLE_RE.search(text):
            unreachable.add(line_no)
            # Also exclude an immediately preceding standalone `default:` label.
            if idx > 0 and DEFAULT_LABEL_RE.match(source_lines[idx - 1]):
                unreachable.add(line_no - 1)
            # Also exclude an immediately following standalone closing `}`.
            if idx + 1 < len(source_lines) and CLOSING_BRACE_RE.match(source_lines[idx + 1]):
                unreachable.add(line_no + 1)
    return unreachable


def extract_snippet(source_lines: list[str], line_start: int, col_start: int, line_end: int, col_end: int) -> str:
    if line_start < 1 or line_start > len(source_lines):
        return ''
    if line_start == line_end:
        line_text = source_lines[line_start - 1]
        c_start = max(0, col_start - 1)
        c_end = max(c_start, col_end - 1) if col_end > col_start else len(line_text)
        snippet = line_text[c_start:c_end].strip()
        return snippet or line_text.strip()
    first_part = source_lines[line_start - 1][max(0, col_start - 1):].strip()
    return f'{first_part} ...'


def group_line_ranges(lines: list[int]) -> list[tuple[int, int]]:
    if not lines:
        return []
    sorted_lines = sorted(lines)
    ranges: list[tuple[int, int]] = []
    start = prev = sorted_lines[0]
    for ln in sorted_lines[1:]:
        if ln == prev + 1:
            prev = ln
        else:
            ranges.append((start, prev))
            start = prev = ln
    ranges.append((start, prev))
    return ranges


def populate_regions_and_functions(
    file_cov: FileDiffCoverage,
    func_entries: list[dict],
    demangled_map: dict[str, str],
    active_diff_lines: list[int],
    active_diff_set: set[int],
    unreachable_lines: set[int],
    include_system_macros: bool,
):
    region_counts: dict[tuple[int, int, int, int], int] = {}
    func_spans: dict[tuple[str, int, int], FunctionSpan] = {}

    executable_diff_lines = [
        ln for ln in active_diff_lines if file_cov.line_stats.get(ln) and file_cov.line_stats[ln].mapped
    ]

    for fn in func_entries:
        fn_regions = fn.get('regions', [])
        if not fn_regions:
            continue
        outer = fn_regions[0]
        f_start, f_end = int(outer[0]), int(outer[2])
        if any(f_start <= ln <= f_end for ln in executable_diff_lines):
            raw_name = fn['name']
            demangled = demangled_map.get(raw_name, raw_name)
            key = (demangled, f_start, f_end)
            if key not in func_spans:
                func_spans[key] = FunctionSpan(
                    name=raw_name,
                    demangled_name=demangled,
                    line_start=f_start,
                    line_end=f_end,
                    count=int(fn.get('count', 0)),
                )
            else:
                func_spans[key].count += int(fn.get('count', 0))

        for reg in fn_regions:
            r_lstart, r_cstart, r_lend, r_cend = int(reg[0]), int(reg[1]), int(reg[2]), int(reg[3])
            r_count, r_file_id, r_kind = int(reg[4]), int(reg[5]), int(reg[7])
            if r_kind != REGION_KIND_CODE or r_file_id != 0:
                continue
            if not include_system_macros and r_lstart == r_lend and r_cstart == r_cend:
                continue
            if r_lstart in unreachable_lines or (
                r_lstart < r_lend
                and all(ln in unreachable_lines for ln in range(r_lstart + 1, r_lend + 1))
            ):
                continue
            r_key = (r_lstart, r_cstart, r_lend, r_cend)
            region_counts[r_key] = region_counts.get(r_key, 0) + r_count

    for span in sorted(func_spans.values(), key=lambda s: (s.line_start, s.demangled_name)):
        file_cov.functions.add(1 if span.count > 0 else 0, 1)
        if span.count == 0:
            file_cov.uncovered_functions.append(span)

    selected_regions: dict[tuple[int, int, int, int], int] = {}
    lines_with_starting_region: set[int] = set()
    for r_key, r_count in region_counts.items():
        if r_key[0] in active_diff_set:
            selected_regions[r_key] = r_count
            lines_with_starting_region.add(r_key[0])

    for ln in active_diff_lines:
        st = file_cov.line_stats.get(ln)
        if not (st and st.mapped) or ln in lines_with_starting_region:
            continue
        enclosing = [
            (r_key, r_count)
            for r_key, r_count in region_counts.items()
            if r_key[0] <= ln <= r_key[2]
        ]
        if enclosing:
            innermost_key, innermost_count = min(
                enclosing,
                key=lambda item: (item[0][2] - item[0][0], item[0][3] - item[0][1]),
            )
            selected_regions[innermost_key] = innermost_count

    uncovered_line_set = set(file_cov.uncovered_lines)
    for r_key in sorted(selected_regions):
        r_count = selected_regions[r_key]
        file_cov.regions.add(1 if r_count > 0 else 0, 1)
        r_lstart, r_cstart, r_lend, r_cend = r_key
        if r_count == 0 and r_lstart in active_diff_set and r_lstart not in uncovered_line_set:
            # Skip multi-line block regions (e.g. `{` at the end of `if (...) {`)
            # whose interior lines are already reported in uncovered_lines.
            if r_lstart < r_lend and any(
                ln in uncovered_line_set for ln in range(r_lstart + 1, r_lend + 1)
            ):
                continue
            file_cov.uncovered_subregions.append(
                CodeRegion(r_lstart, r_cstart, r_lend, r_cend, r_count),
            )


def format_span_loc(line_start: int, col_start: int, line_end: int, col_end: int) -> str:
    if line_start == line_end:
        return f'Line {line_start}:{col_start}-{col_end}'
    return f'Lines {line_start}:{col_start}-{line_end}:{col_end}'


def populate_branches_and_mcdc(
    file_cov: FileDiffCoverage,
    file_entry: dict,
    active_diff_set: set[int],
    unreachable_lines: set[int],
    include_system_macros: bool,
):
    branch_map: dict[tuple[int, int, int, int], list[int]] = {}
    for br in file_entry.get('branches', []):
        b_lstart, b_cstart, b_lend, b_cend = int(br[0]), int(br[1]), int(br[2]), int(br[3])
        b_true, b_false, b_file_id = int(br[4]), int(br[5]), int(br[6])
        if b_file_id != 0:
            continue
        if not include_system_macros and b_lstart == b_lend and b_cstart == b_cend:
            continue
        if b_lstart in unreachable_lines:
            continue
        if not any(ln in active_diff_set for ln in range(b_lstart, b_lend + 1)):
            continue
        b_key = (b_lstart, b_cstart, b_lend, b_cend)
        if b_key not in branch_map:
            branch_map[b_key] = [b_true, b_false]
        else:
            branch_map[b_key][0] += b_true
            branch_map[b_key][1] += b_false

    for b_key in sorted(branch_map):
        b_true, b_false = branch_map[b_key]
        cov_outcomes = (1 if b_true > 0 else 0) + (1 if b_false > 0 else 0)
        file_cov.branches.add(cov_outcomes, 2)
        if cov_outcomes < 2:
            file_cov.uncovered_branches.append(
                BranchRecord(b_key[0], b_key[1], b_key[2], b_key[3], b_true, b_false),
            )

    for mcdc in file_entry.get('mcdc_records', []):
        m_lstart, m_cstart, m_lend, m_cend = int(mcdc[0]), int(mcdc[1]), int(mcdc[2]), int(mcdc[3])
        m_file_id = int(mcdc[6])
        conditions = [bool(c) for c in mcdc[9]] if len(mcdc) > 9 and isinstance(mcdc[9], list) else []
        if m_file_id != 0 or not conditions or m_lstart in unreachable_lines:
            continue
        if not any(ln in active_diff_set for ln in range(m_lstart, m_lend + 1)):
            continue
        cov_conds = sum(1 for c in conditions if c)
        file_cov.mcdc.add(cov_conds, len(conditions))
        if cov_conds < len(conditions):
            file_cov.uncovered_mcdc.append(
                MCDCRecord(m_lstart, m_cstart, m_lend, m_cend, conditions),
            )


def analyze_coverage(
    cov_json: dict,
    file_diffs: dict[str, tuple[list[int], list[tuple[int, int]]]],
    include_unreachable: bool,
    include_system_macros: bool,
) -> list[FileDiffCoverage]:
    """Intersect llvm-cov export JSON with diff line sets across all metrics."""
    files_by_realpath: dict[str, dict] = {}
    functions_by_realpath: dict[str, list[dict]] = {}

    for datum in cov_json.get('data', []):
        for file_entry in datum.get('files', []):
            rp = os.path.realpath(file_entry['filename'])
            files_by_realpath[rp] = file_entry
        for func_entry in datum.get('functions', []):
            filenames = func_entry.get('filenames', [])
            if filenames:
                rp = os.path.realpath(filenames[0])
                functions_by_realpath.setdefault(rp, []).append(func_entry)

    all_func_names = [fn['name'] for funcs in functions_by_realpath.values() for fn in funcs]
    demangled_map = demangle_names(list(set(all_func_names)))

    results: list[FileDiffCoverage] = []

    for rel_path, (diff_lines, hunks) in file_diffs.items():
        abs_path = os.path.realpath(os.path.join(REPO_ROOT, rel_path))
        try:
            with open(abs_path, errors='replace') as f:
                source_lines = [line.rstrip('\r\n') for line in f]
        except OSError:
            source_lines = []

        file_cov = FileDiffCoverage(
            rel_path=rel_path,
            abs_path=abs_path,
            diff_lines=diff_lines,
            hunks=hunks,
        )

        file_entry = files_by_realpath.get(abs_path)
        if not file_entry:
            file_cov.in_coverage_map = False
            results.append(file_cov)
            continue

        unreachable_lines = set() if include_unreachable else find_unreachable_lines(source_lines)
        diff_line_set = set(diff_lines)
        active_diff_lines = sorted(diff_line_set - unreachable_lines)
        file_cov.excluded_unreachable_lines = len(diff_line_set & unreachable_lines)
        active_diff_set = set(active_diff_lines)

        line_stats = compute_line_stats(file_entry.get('segments', []))
        file_cov.line_stats = line_stats
        for ln in active_diff_lines:
            st = line_stats.get(ln)
            if st and st.mapped:
                file_cov.lines.add(1 if st.count > 0 else 0, 1)
                if st.count == 0:
                    file_cov.uncovered_lines.append(ln)
            else:
                file_cov.non_executable_diff_lines += 1

        populate_regions_and_functions(
            file_cov=file_cov,
            func_entries=functions_by_realpath.get(abs_path, []),
            demangled_map=demangled_map,
            active_diff_lines=active_diff_lines,
            active_diff_set=active_diff_set,
            unreachable_lines=unreachable_lines,
            include_system_macros=include_system_macros,
        )
        populate_branches_and_mcdc(
            file_cov=file_cov,
            file_entry=file_entry,
            active_diff_set=active_diff_set,
            unreachable_lines=unreachable_lines,
            include_system_macros=include_system_macros,
        )
        results.append(file_cov)

    return results


def render_text_report(
    diff_desc: str,
    file_results: list[FileDiffCoverage],
    annotate: bool,
    context_lines: int,
):
    totals = {
        'lines': MetricCounts(),
        'regions': MetricCounts(),
        'branches': MetricCounts(),
        'mcdc': MetricCounts(),
        'functions': MetricCounts(),
    }
    total_excluded_unreachable = 0

    for fc in file_results:
        if not fc.in_coverage_map:
            continue
        totals['lines'].add(fc.lines.covered, fc.lines.total)
        totals['regions'].add(fc.regions.covered, fc.regions.total)
        totals['branches'].add(fc.branches.covered, fc.branches.total)
        totals['mcdc'].add(fc.mcdc.covered, fc.mcdc.total)
        totals['functions'].add(fc.functions.covered, fc.functions.total)
        total_excluded_unreachable += fc.excluded_unreachable_lines

    print(f'=== Diff Coverage Report ({diff_desc}) ===\n')
    print(f"  {'Metric':<12} {'Covered / Total':<22} {'Details'}")
    print(f"  {'-' * 12} {'-' * 22} {'-' * 34}")
    print(f"  {'Lines':<12} {totals['lines'].format_summary():<22} Executable lines in diff")
    print(f"  {'Regions':<12} {totals['regions'].format_summary():<22} Sub-line / block AST regions in diff")
    print(f"  {'Branches':<12} {totals['branches'].format_summary():<22} True/False branch outcomes in diff")
    if totals['mcdc'].total > 0:
        print(f"  {'MC/DC':<12} {totals['mcdc'].format_summary():<22} Condition independence pairs in diff")
    print(f"  {'Functions':<12} {totals['functions'].format_summary():<22} Modified functions called >= 1x")

    if total_excluded_unreachable > 0:
        print(f'\n  (Note: Excluded {total_excluded_unreachable} WASM_UNREACHABLE line(s); pass --include-unreachable to include)')

    if len(file_results) > 1:
        print('\n--- Per-File Summary ---')
        for fc in file_results:
            if not fc.in_coverage_map:
                print(f'  {fc.rel_path}: (not in coverage mapping - header/uncompiled)')
                continue
            if fc.lines.total == 0:
                print(f'  {fc.rel_path}: (only comments / non-executable lines changed in diff)')
                continue
            parts = [
                f'Lines: {fc.lines.format_summary()}',
                f'Regions: {fc.regions.format_summary()}',
                f'Branches: {fc.branches.format_summary()}',
            ]
            if fc.mcdc.total > 0:
                parts.append(f'MC/DC: {fc.mcdc.format_summary()}')
            print(f"  {fc.rel_path}\n    {', '.join(parts)}")

    # Print actionable gaps for each file
    any_gaps = False
    for fc in file_results:
        if not fc.in_coverage_map:
            continue
        has_file_gaps = bool(
            fc.uncovered_functions
            or fc.uncovered_lines
            or fc.uncovered_subregions
            or fc.uncovered_branches
            or fc.uncovered_mcdc,
        )
        if not has_file_gaps:
            continue

        if not any_gaps:
            print('\n=== Uncovered / Partially Covered Code in Diff ===')
            any_gaps = True

        try:
            with open(fc.abs_path, errors='replace') as f:
                source_lines = [line.rstrip('\r\n') for line in f]
        except OSError:
            source_lines = []

        print(f'\nFile: {fc.rel_path}')

        if fc.uncovered_functions:
            print('  Uncovered Functions (0 calls):')
            for fn in fc.uncovered_functions:
                print(f'    - Line {fn.line_start}-{fn.line_end}: {fn.demangled_name}')

        if fc.uncovered_lines:
            print('  Uncovered Executable Lines (0x):')
            for start, end in group_line_ranges(fc.uncovered_lines):
                loc = f'Line {start}' if start == end else f'Lines {start}-{end}'
                print(f'    - {loc}:')
                for ln in range(start, end + 1):
                    src = source_lines[ln - 1] if 1 <= ln <= len(source_lines) else ''
                    print(f'        {ln:5d} | {src}')

        if fc.uncovered_subregions:
            print('  Partially Covered Lines (Uncovered Sub-line Regions on Executed Lines):')
            for reg in fc.uncovered_subregions:
                snippet = extract_snippet(
                    source_lines, reg.line_start, reg.col_start, reg.line_end, reg.col_end,
                )
                loc = format_span_loc(reg.line_start, reg.col_start, reg.line_end, reg.col_end)
                full_line = source_lines[reg.line_start - 1].strip() if 1 <= reg.line_start <= len(source_lines) else ''
                context_suffix = f' (in `{full_line}`)' if reg.line_start == reg.line_end and full_line != snippet else ''
                print(
                    f'    - {loc} (0x): `{snippet}`{context_suffix}',
                )

        if fc.uncovered_branches:
            print('  Uncovered / One-Sided Branches:')
            for br in fc.uncovered_branches:
                snippet = extract_snippet(
                    source_lines, br.line_start, br.col_start, br.line_end, br.col_end,
                )
                loc = format_span_loc(br.line_start, br.col_start, br.line_end, br.col_end)
                if br.true_count == 0 and br.false_count == 0:
                    status = 'never reached (True: 0x, False: 0x)'
                elif br.true_count == 0:
                    status = f'missing TRUE branch (True: 0x, False: {br.false_count}x)'
                else:
                    status = f'missing FALSE branch (True: {br.true_count}x, False: 0x)'
                print(
                    f'    - {loc} `{snippet}` -> {status}',
                )

        if fc.uncovered_mcdc:
            print('  Uncovered MC/DC Condition Independence Pairs:')
            for rec in fc.uncovered_mcdc:
                snippet = extract_snippet(
                    source_lines, rec.line_start, rec.col_start, rec.line_end, rec.col_end,
                )
                loc = format_span_loc(rec.line_start, rec.col_start, rec.line_end, rec.col_end)
                missing_conds = [f'C{i + 1}' for i, cov in enumerate(rec.conditions) if not cov]
                print(
                    f"    - {loc} `{snippet}` -> "
                    f"missing independence pair for {', '.join(missing_conds)}",
                )

    if not any_gaps and totals['lines'].total > 0:
        print('\nAll executable lines, regions, and branches in the diff are 100% covered!')

    if annotate:
        print('\n=== Annotated Diff Hunks ===')
        for fc in file_results:
            if not fc.in_coverage_map:
                continue
            try:
                with open(fc.abs_path, errors='replace') as f:
                    source_lines = [line.rstrip('\r\n') for line in f]
            except OSError:
                continue
            print(f'\n--- {fc.rel_path} ---')
            diff_set = set(fc.diff_lines)
            branches_by_line: dict[int, list[BranchRecord]] = {}
            for br in fc.uncovered_branches:
                branches_by_line.setdefault(br.line_start, []).append(br)

            for start, count in fc.hunks:
                lo = max(1, start - context_lines)
                hi = min(len(source_lines), start + count - 1 + context_lines)
                print(f'@@ lines {lo}-{hi} @@')
                for ln in range(lo, hi + 1):
                    marker = '+' if ln in diff_set else ' '
                    st = fc.line_stats.get(ln)
                    if st and st.mapped:
                        cnt_str = f'{st.count:6d}x' if st.count > 0 else '  #####'
                    else:
                        cnt_str = '       '
                    print(f'{marker} {ln:5d} | {cnt_str} | {source_lines[ln - 1]}')
                    for br in branches_by_line.get(ln, []):
                        print(
                            f'        |         |   ^-- Branch ({br.line_start}:{br.col_start}): '
                            f'[True: {br.true_count}x, False: {br.false_count}x]',
                        )


def render_markdown_report(
    diff_desc: str,
    file_results: list[FileDiffCoverage],
    annotate: bool,
    context_lines: int,
) -> str:
    lines: list[str] = [f'## Diff Coverage Report ({diff_desc})', '']
    if not file_results:
        lines.append(f'No modified C/C++ source files found in {diff_desc}.')
        return '\n'.join(lines)

    totals = {
        'lines': MetricCounts(),
        'regions': MetricCounts(),
        'branches': MetricCounts(),
        'mcdc': MetricCounts(),
        'functions': MetricCounts(),
    }
    total_excluded_unreachable = 0

    for fc in file_results:
        if not fc.in_coverage_map:
            continue
        totals['lines'].add(fc.lines.covered, fc.lines.total)
        totals['regions'].add(fc.regions.covered, fc.regions.total)
        totals['branches'].add(fc.branches.covered, fc.branches.total)
        totals['mcdc'].add(fc.mcdc.covered, fc.mcdc.total)
        totals['functions'].add(fc.functions.covered, fc.functions.total)
        total_excluded_unreachable += fc.excluded_unreachable_lines

    lines.extend([
        '| Metric | Covered / Total | Details |',
        '| :--- | :--- | :--- |',
        f"| **Lines** | {totals['lines'].format_summary()} | Executable lines in diff |",
        f"| **Regions** | {totals['regions'].format_summary()} | Sub-line / block AST regions in diff |",
        f"| **Branches** | {totals['branches'].format_summary()} | True/False branch outcomes in diff |",
    ])
    if totals['mcdc'].total > 0:
        lines.append(
            f"| **MC/DC** | {totals['mcdc'].format_summary()} | Condition independence pairs in diff |",
        )
    lines.append(
        f"| **Functions** | {totals['functions'].format_summary()} | Modified functions called >= 1x |",
    )

    if total_excluded_unreachable > 0:
        lines.extend([
            '',
            f'*(Note: Excluded {total_excluded_unreachable} `WASM_UNREACHABLE` line(s); '
            'pass `--include-unreachable` to include)*',
        ])

    if len(file_results) > 1:
        has_mcdc = any(fc.in_coverage_map and fc.mcdc.total > 0 for fc in file_results)
        lines.extend(['', '### Per-File Summary', ''])
        if has_mcdc:
            lines.extend([
                '| File | Lines | Regions | Branches | MC/DC |',
                '| :--- | :--- | :--- | :--- | :--- |',
            ])
        else:
            lines.extend([
                '| File | Lines | Regions | Branches |',
                '| :--- | :--- | :--- | :--- |',
            ])
        for fc in file_results:
            if not fc.in_coverage_map:
                cols = ['*(not in coverage mapping - header/uncompiled)*', '-', '-']
                if has_mcdc:
                    cols.append('-')
            elif fc.lines.total == 0:
                cols = ['*(only comments / non-executable lines changed)*', '-', '-']
                if has_mcdc:
                    cols.append('-')
            else:
                cols = [
                    fc.lines.format_summary(),
                    fc.regions.format_summary(),
                    fc.branches.format_summary(),
                ]
                if has_mcdc:
                    cols.append(fc.mcdc.format_summary() if fc.mcdc.total > 0 else '-')
            lines.append(f"| `{fc.rel_path}` | {' | '.join(cols)} |")

    any_gaps = False
    for fc in file_results:
        if not fc.in_coverage_map:
            continue
        has_file_gaps = bool(
            fc.uncovered_functions
            or fc.uncovered_lines
            or fc.uncovered_subregions
            or fc.uncovered_branches
            or fc.uncovered_mcdc,
        )
        if not has_file_gaps:
            continue

        if not any_gaps:
            lines.extend(['', '### Uncovered / Partially Covered Code in Diff'])
            any_gaps = True

        try:
            with open(fc.abs_path, errors='replace') as f:
                source_lines = [line.rstrip('\r\n') for line in f]
        except OSError:
            source_lines = []

        lines.extend(['', f'#### `{fc.rel_path}`'])

        if fc.uncovered_functions:
            lines.append('- **Uncovered Functions (0 calls):**')
            for fn in fc.uncovered_functions:
                lines.append(f'  - Line {fn.line_start}-{fn.line_end}: `{fn.demangled_name}`')

        if fc.uncovered_lines:
            lines.append('- **Uncovered Executable Lines (0x):**')
            for start, end in group_line_ranges(fc.uncovered_lines):
                loc = f'Line {start}' if start == end else f'Lines {start}-{end}'
                lines.append(f'  - {loc}:')
                lines.append('    ```cpp')
                for ln in range(start, end + 1):
                    src = source_lines[ln - 1] if 1 <= ln <= len(source_lines) else ''
                    lines.append(f'    {ln:5d} | {src}')
                lines.append('    ```')

        if fc.uncovered_subregions:
            lines.append('- **Partially Covered Lines (Uncovered Sub-line Regions on Executed Lines):**')
            for reg in fc.uncovered_subregions:
                snippet = extract_snippet(
                    source_lines, reg.line_start, reg.col_start, reg.line_end, reg.col_end,
                )
                loc = format_span_loc(reg.line_start, reg.col_start, reg.line_end, reg.col_end)
                full_line = source_lines[reg.line_start - 1].strip() if 1 <= reg.line_start <= len(source_lines) else ''
                context_suffix = f' (in `{full_line}`)' if reg.line_start == reg.line_end and full_line != snippet else ''
                lines.append(f'  - {loc} (0x): `{snippet}`{context_suffix}')

        if fc.uncovered_branches:
            lines.append('- **Uncovered / One-Sided Branches:**')
            for br in fc.uncovered_branches:
                snippet = extract_snippet(
                    source_lines, br.line_start, br.col_start, br.line_end, br.col_end,
                )
                loc = format_span_loc(br.line_start, br.col_start, br.line_end, br.col_end)
                if br.true_count == 0 and br.false_count == 0:
                    status = 'never reached (True: 0x, False: 0x)'
                elif br.true_count == 0:
                    status = f'missing TRUE branch (True: 0x, False: {br.false_count}x)'
                else:
                    status = f'missing FALSE branch (True: {br.true_count}x, False: 0x)'
                lines.append(f'  - {loc} `{snippet}` -> {status}')

        if fc.uncovered_mcdc:
            lines.append('- **Uncovered MC/DC Condition Independence Pairs:**')
            for rec in fc.uncovered_mcdc:
                snippet = extract_snippet(
                    source_lines, rec.line_start, rec.col_start, rec.line_end, rec.col_end,
                )
                loc = format_span_loc(rec.line_start, rec.col_start, rec.line_end, rec.col_end)
                missing_conds = [f'C{i + 1}' for i, cov in enumerate(rec.conditions) if not cov]
                lines.append(
                    f"  - {loc} `{snippet}` -> "
                    f"missing independence pair for {', '.join(missing_conds)}",
                )

    if not any_gaps and totals['lines'].total > 0:
        lines.extend([
            '',
            'All executable lines, regions, and branches in the diff are 100% covered!',
        ])

    if annotate and any(fc.in_coverage_map for fc in file_results):
        lines.extend([
            '',
            '<details>',
            '<summary>Annotated Diff Hunks</summary>',
            '',
        ])
        for fc in file_results:
            if not fc.in_coverage_map:
                continue
            try:
                with open(fc.abs_path, errors='replace') as f:
                    source_lines = [line.rstrip('\r\n') for line in f]
            except OSError:
                continue
            lines.extend([f'#### `{fc.rel_path}`', '', '```text'])
            diff_set = set(fc.diff_lines)
            branches_by_line: dict[int, list[BranchRecord]] = {}
            for br in fc.uncovered_branches:
                branches_by_line.setdefault(br.line_start, []).append(br)

            for start, count in fc.hunks:
                lo = max(1, start - context_lines)
                hi = min(len(source_lines), start + count - 1 + context_lines)
                lines.append(f'@@ lines {lo}-{hi} @@')
                for ln in range(lo, hi + 1):
                    marker = '+' if ln in diff_set else ' '
                    st = fc.line_stats.get(ln)
                    if st and st.mapped:
                        cnt_str = f'{st.count:6d}x' if st.count > 0 else '  #####'
                    else:
                        cnt_str = '       '
                    lines.append(f'{marker} {ln:5d} | {cnt_str} | {source_lines[ln - 1]}')
                    for br in branches_by_line.get(ln, []):
                        lines.append(
                            f'        |         |   ^-- Branch ({br.line_start}:{br.col_start}): '
                            f'[True: {br.true_count}x, False: {br.false_count}x]',
                        )
            lines.extend(['```', ''])
        lines.append('</details>')

    return '\n'.join(lines)


def escape_github_annotation(msg: str) -> str:
    return msg.replace('%', '%25').replace('\r', '%0D').replace('\n', '%0A')


def emit_github_annotations(file_results: list[FileDiffCoverage]):
    for fc in file_results:
        if not fc.in_coverage_map:
            continue
        try:
            with open(fc.abs_path, errors='replace') as f:
                source_lines = [line.rstrip('\r\n') for line in f]
        except OSError:
            source_lines = []

        uncovered_line_set = set(fc.uncovered_lines)

        for start, end in group_line_ranges(fc.uncovered_lines):
            loc = f'Line {start}' if start == end else f'Lines {start}-{end}'
            msg = escape_github_annotation(f'{loc} not executed by tests (0x)')
            print(
                f'::warning file={fc.rel_path},line={start},endLine={end},'
                f'title=Uncovered diff lines::{msg}',
            )

        for reg in fc.uncovered_subregions:
            snippet = extract_snippet(
                source_lines, reg.line_start, reg.col_start, reg.line_end, reg.col_end,
            )
            msg = escape_github_annotation(
                f'Sub-region `{snippet}` on executed line was never reached (0x)',
            )
            print(
                f'::warning file={fc.rel_path},line={reg.line_start},endLine={reg.line_end},'
                f'col={reg.col_start},endColumn={reg.col_end},'
                f'title=Uncovered sub-region::{msg}',
            )

        for br in fc.uncovered_branches:
            if br.line_start in uncovered_line_set:
                continue
            snippet = extract_snippet(
                source_lines, br.line_start, br.col_start, br.line_end, br.col_end,
            )
            if br.true_count == 0 and br.false_count == 0:
                status = 'never reached (True: 0x, False: 0x)'
            elif br.true_count == 0:
                status = f'missing TRUE branch (True: 0x, False: {br.false_count}x)'
            else:
                status = f'missing FALSE branch (True: {br.true_count}x, False: 0x)'
            msg = escape_github_annotation(f'Branch `{snippet}` -> {status}')
            print(
                f'::warning file={fc.rel_path},line={br.line_start},endLine={br.line_end},'
                f'col={br.col_start},endColumn={br.col_end},'
                f'title=One-sided branch in diff::{msg}',
            )

        for rec in fc.uncovered_mcdc:
            if rec.line_start in uncovered_line_set:
                continue
            snippet = extract_snippet(
                source_lines, rec.line_start, rec.col_start, rec.line_end, rec.col_end,
            )
            missing_conds = [f'C{i + 1}' for i, cov in enumerate(rec.conditions) if not cov]
            msg = escape_github_annotation(
                f"Decision `{snippet}` -> missing MC/DC independence pair for {', '.join(missing_conds)}",
            )
            print(
                f'::warning file={fc.rel_path},line={rec.line_start},endLine={rec.line_end},'
                f'col={rec.col_start},endColumn={rec.col_end},'
                f'title=Uncovered MC/DC condition::{msg}',
            )


def render_json_report(diff_desc: str, file_results: list[FileDiffCoverage]) -> str:
    totals = {
        'lines': MetricCounts(),
        'regions': MetricCounts(),
        'branches': MetricCounts(),
        'mcdc': MetricCounts(),
        'functions': MetricCounts(),
    }
    for fc in file_results:
        if not fc.in_coverage_map:
            continue
        totals['lines'].add(fc.lines.covered, fc.lines.total)
        totals['regions'].add(fc.regions.covered, fc.regions.total)
        totals['branches'].add(fc.branches.covered, fc.branches.total)
        totals['mcdc'].add(fc.mcdc.covered, fc.mcdc.total)
        totals['functions'].add(fc.functions.covered, fc.functions.total)

    payload = {
        'diff_target': diff_desc,
        'totals': {
            k: {'covered': v.covered, 'total': v.total, 'percent': v.percent}
            for k, v in totals.items()
        },
        'files': [
            {
                'file': fc.rel_path,
                'in_coverage_map': fc.in_coverage_map,
                'metrics': {
                    'lines': {'covered': fc.lines.covered, 'total': fc.lines.total, 'percent': fc.lines.percent},
                    'regions': {'covered': fc.regions.covered, 'total': fc.regions.total, 'percent': fc.regions.percent},
                    'branches': {'covered': fc.branches.covered, 'total': fc.branches.total, 'percent': fc.branches.percent},
                    'mcdc': {'covered': fc.mcdc.covered, 'total': fc.mcdc.total, 'percent': fc.mcdc.percent},
                    'functions': {'covered': fc.functions.covered, 'total': fc.functions.total, 'percent': fc.functions.percent},
                },
                'uncovered_functions': [
                    {'name': fn.demangled_name, 'line_start': fn.line_start, 'line_end': fn.line_end}
                    for fn in fc.uncovered_functions
                ],
                'uncovered_lines': fc.uncovered_lines,
                'uncovered_subregions': [
                    {
                        'line_start': r.line_start,
                        'col_start': r.col_start,
                        'line_end': r.line_end,
                        'col_end': r.col_end,
                    }
                    for r in fc.uncovered_subregions
                ],
                'uncovered_branches': [
                    {
                        'line_start': b.line_start,
                        'col_start': b.col_start,
                        'line_end': b.line_end,
                        'col_end': b.col_end,
                        'true_count': b.true_count,
                        'false_count': b.false_count,
                    }
                    for b in fc.uncovered_branches
                ],
            }
            for fc in file_results
        ],
    }
    return json.dumps(payload, indent=2)


def main():
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        'base',
        nargs='?',
        default=None,
        help='Git ref or Jujutsu revset to diff against (default: branch changes vs trunk/upstream)',
    )
    parser.add_argument(
        '--base',
        dest='base_flag',
        default=None,
        help='Git ref or Jujutsu revset to diff against (overrides positional base)',
    )
    parser.add_argument(
        '-r',
        '--revisions',
        default=None,
        metavar='REVSET',
        help='Revision(s) to analyze (e.g. Jujutsu `-r @-`, `-r "trunk()..@"`, or Git commit/range)',
    )
    parser.add_argument(
        '--vcs',
        choices=['auto', 'git', 'jj'],
        default='auto',
        help='Version control system to query for diff hunks (default: auto)',
    )
    parser.add_argument(
        '--files',
        '--file',
        nargs='+',
        default=None,
        metavar='PATTERN',
        help='Restrict report to modified C/C++ files matching repo-relative path, basename, or glob',
    )
    parser.add_argument(
        '--staged',
        action='store_true',
        help='Analyze only staged changes (git diff --cached)',
    )
    parser.add_argument(
        '-B',
        '--build-dir',
        default=None,
        help='CMake build directory configured with coverage flags (default: auto-detect out/cov, build/cov, .)',
    )
    parser.add_argument(
        '--lit',
        nargs='+',
        metavar='TEST',
        help='Run binaryen-lit on the specified test file(s)/directories to collect coverage',
    )
    parser.add_argument(
        '--gtest',
        nargs='?',
        const='*',
        default=None,
        metavar='FILTER',
        help='Run binaryen-unittests (optionally with --gtest_filter=FILTER) to collect coverage',
    )
    parser.add_argument(
        '--run',
        action='append',
        metavar='CMD',
        help='Run custom command(s) with LLVM_PROFILE_FILE set to collect coverage',
    )
    parser.add_argument(
        '--append',
        action='store_true',
        help='Keep existing .profraw files when running tests via --lit/--gtest/--run',
    )
    parser.add_argument(
        '--clear',
        action='store_true',
        help='Clear all collected .profraw and .profdata files in the build directory',
    )
    parser.add_argument(
        '--profdata',
        default=None,
        help='Explicit path to a merged .profdata file',
    )
    parser.add_argument(
        '--object',
        action='append',
        dest='objects',
        metavar='BIN',
        help='Explicit instrumented library/executable path(s) for llvm-cov (auto-detected by default)',
    )
    parser.add_argument(
        '-a',
        '--annotate',
        action='store_true',
        help='Print annotated diff hunks with per-line execution counts and branch counts',
    )
    parser.add_argument(
        '-C',
        '--context',
        type=int,
        default=2,
        help='Number of context lines around annotated diff hunks (default: 2)',
    )
    parser.add_argument(
        '--json',
        action='store_true',
        help='Emit coverage report as JSON',
    )
    parser.add_argument(
        '--markdown',
        action='store_true',
        help='Emit coverage report as GitHub-flavored Markdown (e.g. for $GITHUB_STEP_SUMMARY)',
    )
    parser.add_argument(
        '--github-annotations',
        action='store_true',
        help='Emit GitHub Actions workflow warning annotations for uncovered diff code',
    )
    parser.add_argument(
        '--include-unreachable',
        action='store_true',
        help='Include WASM_UNREACHABLE lines in coverage totals',
    )
    parser.add_argument(
        '--include-system-macros',
        action='store_true',
        help='Include 0-width system macro expansions (such as assert() internal branches)',
    )
    parser.add_argument(
        '--fail-under-lines',
        type=float,
        default=None,
        metavar='PCT',
        help='Exit with code 1 if diff line coverage percentage is below PCT',
    )
    parser.add_argument(
        '--fail-under-regions',
        type=float,
        default=None,
        metavar='PCT',
        help='Exit with code 1 if diff region coverage percentage is below PCT',
    )
    parser.add_argument(
        '--fail-under-branches',
        type=float,
        default=None,
        metavar='PCT',
        help='Exit with code 1 if diff branch coverage percentage is below PCT',
    )
    parser.add_argument(
        '--llvm-cov',
        default=None,
        help='Path to llvm-cov binary',
    )
    parser.add_argument(
        '--llvm-profdata',
        default=None,
        help='Path to llvm-profdata binary',
    )

    argv = sys.argv[2:] if len(sys.argv) > 2 and sys.argv[1] == '--' and sys.argv[2].startswith('-') else sys.argv[1:]
    args = parser.parse_args(argv)
    if args.base in {'-h', '--help'}:
        parser.print_help()
        sys.exit(0)
    base_ref = args.base_flag or args.base

    if args.revisions and base_ref:
        print('Error: Cannot combine -r/--revisions with a base ref.', file=sys.stderr)
        sys.exit(2)
    if args.revisions and args.staged:
        print('Error: Cannot combine -r/--revisions with --staged.', file=sys.stderr)
        sys.exit(2)

    vcs = detect_vcs(args.vcs)

    # 1. Verify llvm-cov and llvm-profdata are installed.
    llvm_cov = find_llvm_tool('llvm-cov', args.llvm_cov)
    llvm_profdata = find_llvm_tool('llvm-profdata', args.llvm_profdata)
    if not llvm_cov or not llvm_profdata:
        missing = [name for name, path in [('llvm-cov', llvm_cov), ('llvm-profdata', llvm_profdata)] if not path]
        print(
            f"Error: Required LLVM coverage tool(s) not found in PATH: {', '.join(missing)}\n"
            'Install the llvm package (e.g. `sudo apt-get install llvm`) or pass --llvm-cov / --llvm-profdata.',
            file=sys.stderr,
        )
        sys.exit(2)

    # 2. Discover & validate the CMake build directory.
    build_dir, is_valid_config, reason, _cache = discover_build_dir(args.build_dir)
    if not is_valid_config:
        print_setup_instructions(reason, args.build_dir or 'out/cov')
        sys.exit(2)

    if args.clear:
        removed = clear_coverage_profiles(build_dir)
        rel_build = os.path.relpath(build_dir, REPO_ROOT)
        print(f"Cleared {removed} coverage profile file(s) from '{rel_build}'.")
        if not (args.lit or args.gtest is not None or args.run):
            sys.exit(0)

    # 3. Collect diff hunks first so we know which files/binaries are involved.
    diff_desc, file_diffs = get_diff_lines(
        vcs=vcs,
        base_ref=base_ref,
        revisions=args.revisions,
        staged_only=args.staged,
        file_patterns=args.files,
    )
    if not file_diffs:
        if args.json:
            print(render_json_report(diff_desc, []))
        elif args.markdown:
            print(render_markdown_report(diff_desc, [], args.annotate, args.context))
        else:
            tip = (
                f'(Tip: pass `-r @-` or a base revset such as `{SCRIPT_PATH} main` to compare other revisions.)'
                if vcs == 'jj'
                else f'(Tip: pass a base ref such as `{SCRIPT_PATH} origin/main` or `HEAD~1` to compare committed changes.)'
            )
            print(f'No modified C/C++ source files found in {diff_desc}.\n{tip}')
        sys.exit(0)

    # 4. Run tests if --lit, --gtest, or --run was specified.
    profraw_files: list[str] | None = None
    if args.lit or args.gtest is not None or args.run:
        _profraw_dir, profraw_files = run_test_commands(
            build_dir=build_dir,
            lit_tests=args.lit,
            gtest_filter=args.gtest,
            custom_cmds=args.run,
            append_profiles=args.append,
        )

    # 5. Locate instrumented binary/library objects.
    objects = find_coverage_objects(
        build_dir=build_dir,
        explicit_objects=args.objects,
        diff_rel_paths=list(file_diffs.keys()),
        used_gtest=args.gtest is not None,
    )
    if not objects:
        rel_build = os.path.relpath(build_dir, REPO_ROOT)
        print(
            f"Error: No built libraries or executables found in '{rel_build}'.\n"
            f'Build your targets first, e.g.:\n  ninja -C {rel_build} wasm-opt binaryen-unittests',
            file=sys.stderr,
        )
        sys.exit(2)

    # 6. Locate or merge .profdata (invalidating any profiles older than rebuilt objects).
    profdata_path = resolve_profdata(
        build_dir=build_dir,
        llvm_profdata=llvm_profdata,
        explicit_profdata=args.profdata,
        profraw_files=profraw_files,
        objects=objects,
    )
    if not profdata_path:
        print_missing_profile_instructions(build_dir)
        sys.exit(2)

    # 7. Run `llvm-cov export` restricted to the modified files in the diff.
    source_paths = [os.path.join(REPO_ROOT, rel) for rel in file_diffs]
    cov_cmd = [
        llvm_cov,
        'export',
        '--format=text',
        '--skip-expansions',
        f'--instr-profile={profdata_path}',
        objects[0],
        *[f'--object={obj}' for obj in objects[1:]],
        '--',
        *source_paths,
    ]
    cov_res = subprocess.run(cov_cmd, cwd=REPO_ROOT, capture_output=True, text=True)
    if cov_res.returncode != 0:
        rel_build = os.path.relpath(build_dir, REPO_ROOT)
        print(
            f'Error running llvm-cov export:\n{cov_res.stderr.strip()}\n',
            file=sys.stderr,
        )
        if 'No coverage data found' in cov_res.stderr or 'Failed to load coverage' in cov_res.stderr:
            print_setup_instructions(
                f"Binaries in '{rel_build}' do not contain LLVM coverage mapping sections.",
                rel_build,
            )
        sys.exit(2)

    cov_json = json.loads(cov_res.stdout)
    file_results = analyze_coverage(
        cov_json=cov_json,
        file_diffs=file_diffs,
        include_unreachable=args.include_unreachable,
        include_system_macros=args.include_system_macros,
    )

    if args.json:
        print(render_json_report(diff_desc, file_results))
    elif args.markdown:
        print(
            render_markdown_report(
                diff_desc=diff_desc,
                file_results=file_results,
                annotate=args.annotate,
                context_lines=args.context,
            ),
        )
    else:
        render_text_report(
            diff_desc=diff_desc,
            file_results=file_results,
            annotate=args.annotate,
            context_lines=args.context,
        )

    if args.github_annotations:
        emit_github_annotations(file_results)

    # 8. Check optional threshold gates.
    failed_gate = False
    for metric_name, threshold in [
        ('lines', args.fail_under_lines),
        ('regions', args.fail_under_regions),
        ('branches', args.fail_under_branches),
    ]:
        if threshold is None:
            continue
        agg = MetricCounts()
        for fc in file_results:
            if fc.in_coverage_map:
                m: MetricCounts = getattr(fc, metric_name)
                agg.add(m.covered, m.total)
        if agg.percent is not None and agg.percent < threshold:
            print(
                f'FAIL: Diff {metric_name} coverage ({agg.percent:.1f}%) is below threshold ({threshold:.1f}%).',
                file=sys.stderr,
            )
            failed_gate = True

    if failed_gate:
        sys.exit(1)


if __name__ == '__main__':
    main()
