#!/usr/bin/env python3
# This file is part of Eigen, a lightweight C++ template library
# for linear algebra.
#
# Copyright (C) 2026 The Eigen Authors
#
# This Source Code Form is subject to the terms of the Mozilla
# Public License v. 2.0. If a copy of the MPL was not distributed
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# REUSE-IgnoreStart
"""
Insert per-file SPDX license tags across the Eigen tree.

Idempotent: files already containing an SPDX-License-Identifier tag are left
untouched. Re-running after a clean run produces no changes.

The license id assigned to each file is determined by `classify(path)`:
- LAPACKE/BLAS bridges with Intel copyright    -> BSD-3-Clause
- MORSE-derived cmake/Find*.cmake modules      -> BSD-3-Clause
- Reference-BLAS Fortran tests blas/testing/*.f -> BSD-3-Clause
- LevenbergMarquardt MINPACK-derived headers   -> MPL-2.0 AND LicenseRef-MINPACK
- Everything else under repo                    -> MPL-2.0

The comment style is determined by the file extension:
- C / C++ / CUDA / Inc / Fortran-fixed-form ('//', '#', '*' etc.)

Files explicitly excluded from inline SPDX (handled instead by REUSE.toml):
- LICENSES/, COPYING.*, LICENSE                                (license texts)
- *.dox, *.in, *.md, *.dat, *.png, README*, INSTALL,           (assets/templates)
  *.def, *.natvis, *.css, *.xsl, *.preamble, *.traits, *.krazy
- .git*, .clang*, .coderabbit*, .gitlab/                       (config dotfiles)
- failtest/*.cpp                                               (trivial stubs)
- signature_of_eigen3_matrix_library                           (sentinel file)
"""
# REUSE-IgnoreEnd

from __future__ import annotations

import argparse
import re
import subprocess
import sys
from pathlib import Path
from typing import Iterable

REPO_ROOT = Path(__file__).resolve().parent.parent

SPDX_RE = re.compile(r"SPDX-License-Identifier\s*:")
# Match REUSE's own copyright detection (case-sensitive `Copyright`); lowercase
# `copyright` lines (typo in some headers) won't be recognised, so we'll still
# inject `SPDX-FileCopyrightText` for those files.
COPYRIGHT_RE = re.compile(r"Copyright\b")


# ---------------------------------------------------------------------------
# Path classification
# ---------------------------------------------------------------------------

# Files containing an Intel BSD-3-Clause copyright header (LAPACKE/BLAS bridges).
# Match by content rather than path so this stays correct as files are added.
INTEL_BSD_MARKER = b"Copyright (c) 2011, Intel Corporation"
INTEL_BSD_MARKER_2010 = b"Copyright (c) 2010, Intel Corp"

# MORSE-derived cmake modules (Univ. of Tennessee 2009-2014).
MORSE_MARKER = b"@copyright (c) 2009-2014 The University of Tennessee"

# Header marker for the LevenbergMarquardt MINPACK-derived files.
MINPACK_MARKER = b"Minpack license"

# Reference-BLAS / LAPACK Fortran (Univ. of Tennessee/Berkeley/Colorado Denver).
REFBLAS_MARKERS = (
    b"Reference BLAS is a software package",
    b"LAPACK is a software package provided by Univ. of Tennessee",
)

# Apache-2.0 — TensorFlow-derived BFloat16, Codeplay FindComputeCpp.cmake.
APACHE_MARKER = b"Licensed under the Apache License"


def in_failtest(rel: Path) -> bool:
    return rel.parts and rel.parts[0] == "failtest"


# Bulk-mapped via REUSE.toml — never insert inline SPDX into these.
SKIP_BY_NAME = {
    "CHANGELOG.md",
    "INSTALL",
    "README.md",
    "signature_of_eigen3_matrix_library",
    "CLAUDE.md",
}

SKIP_BY_SUFFIX = {
    ".dox",
    ".in",
    ".dat",
    ".png",
    ".svg",
    ".jpg",
    ".jpeg",
    ".gif",
    ".md",
    ".txt",        # README.txt, *.txt config — handled by REUSE.toml
    ".def",        # blas/eigen_blas.def, lapack/eigen_lapack*.def
    ".natvis",
    ".css",
    ".xsl",
    ".preamble",
    ".traits",
    ".krazy",
    ".yaml",       # .coderabbit.yaml — REUSE.toml
    ".entry",      # doc/examples/make_circulant.cpp.entry / .evaluator / ...
    ".evaluator",
    ".expression",
    ".main",
}

# Top-level / specially-handled excluded paths (relative to repo root).
SKIP_PATHS = {
    ".clang-format",
    ".clang-tidy",
    ".coderabbit.yaml",
    ".git-blame-ignore-revs",
    ".gitattributes",
    ".gitignore",
    "LICENSE",
    "REUSE.toml",
}


def is_skipped(rel: Path) -> bool:
    name = rel.name
    posix = rel.as_posix()
    if posix in SKIP_PATHS:
        return True
    if posix.startswith("LICENSES/") or posix.startswith("COPYING"):
        return True
    if posix.startswith(".gitlab/") or posix.startswith(".git/"):
        return True
    if in_failtest(rel) and rel.suffix == ".cpp":
        return True
    # Recognise CMakeLists.txt by name BEFORE the .txt suffix-skip below.
    if name == "CMakeLists.txt":
        return False
    if name in SKIP_BY_NAME:
        return True
    if rel.suffix in SKIP_BY_SUFFIX:
        return True
    return False


def classify(rel: Path, content: bytes) -> str:
    """Return the SPDX-License-Identifier expression for a file."""
    if INTEL_BSD_MARKER in content or INTEL_BSD_MARKER_2010 in content:
        return "BSD-3-Clause"
    if MORSE_MARKER in content:
        return "BSD-3-Clause"
    if MINPACK_MARKER in content:
        return "MPL-2.0 AND LicenseRef-MINPACK"
    if any(m in content for m in REFBLAS_MARKERS):
        return "BSD-3-Clause"
    if APACHE_MARKER in content:
        return "Apache-2.0"
    return "MPL-2.0"


# ---------------------------------------------------------------------------
# Comment-style dispatch
# ---------------------------------------------------------------------------

# (suffix -> comment prefix). Files without a known suffix are handled by name.
SLASH_LANGUAGES = {".h", ".hh", ".cpp", ".cc", ".c", ".cu", ".inc", ".js"}
HASH_LANGUAGES = {".cmake", ".sh", ".py", ".ps1", ".yml", ".cfg"}
FORTRAN_LANGUAGES = {".f", ".F", ".f90"}


def is_eigen_umbrella_header(rel: Path) -> bool:
    """`Eigen/Core`, `unsupported/Eigen/Tensor`, etc. — extensionless C++ headers."""
    parts = rel.parts
    if rel.suffix:
        return False
    if len(parts) >= 2 and parts[0] == "Eigen" and parts[-1][:1].isupper():
        return len(parts) == 2
    if (
        len(parts) >= 3
        and parts[0] == "unsupported"
        and parts[1] == "Eigen"
        and parts[-1][:1].isupper()
    ):
        # unsupported/Eigen/Tensor, ...
        return True
    return False


def has_shebang(path: Path) -> bool:
    try:
        with path.open("rb") as f:
            return f.read(2) == b"#!"
    except OSError:
        return False


def comment_prefix_for(rel: Path, full: Path | None = None) -> str | None:
    if rel.suffix in SLASH_LANGUAGES:
        return "//"
    if rel.suffix in HASH_LANGUAGES:
        return "#"
    if rel.suffix in FORTRAN_LANGUAGES:
        return "*>"
    name = rel.name
    if name == "CMakeLists.txt":
        return "#"
    if is_eigen_umbrella_header(rel):
        return "//"
    # Extensionless executable scripts (e.g. scripts/eigen_gen_docs).
    if not rel.suffix and full is not None and has_shebang(full):
        return "#"
    return None


# ---------------------------------------------------------------------------
# Insertion strategy
# ---------------------------------------------------------------------------

def insert_spdx(
    path: Path, content: bytes, spdx_id: str, comment: str
) -> bytes | None:
    """Return new file bytes with the SPDX line inserted, or None for no-op."""
    full_text = content.decode("utf-8", errors="replace")
    if SPDX_RE.search(full_text):
        return None  # Already tagged.

    head = full_text[:4096]
    has_copyright = COPYRIGHT_RE.search(head) is not None

    # Match the file's line-ending style (CRLF vs LF) so we don't introduce
    # mixed endings that clang-format will then "fix".
    eol = "\r\n" if b"\r\n" in content[:4096] else "\n"

    # REUSE-IgnoreStart
    spdx_lines = []
    if not has_copyright:
        spdx_lines.append(f"{comment} SPDX-FileCopyrightText: The Eigen Authors{eol}")
    spdx_lines.append(f"{comment} SPDX-License-Identifier: {spdx_id}{eol}")
    spdx_line = "".join(spdx_lines).encode()
    # REUSE-IgnoreEnd

    lines = full_text.splitlines(keepends=True)

    # Two header families to consider:
    #
    # (a) Existing C-line-comment MPL prose ("// This file is part of Eigen, ...
    #     // ... obtain one at http://mozilla.org/MPL/2.0/."): append SPDX
    #     directly after the prose block (last consecutive comment line at
    #     top-of-file).
    #
    # (b) Existing C-block-comment header (Intel "/* Copyright (c) 2011, Intel
    #     Corporation ... */"): append a comment line right after the closing
    #     "*/".
    #
    # (c) Hash-comment prose (.cmake / .gitlab-ci.yml / etc.): append after the
    #     last consecutive '#'-comment line at top.
    #
    # (d) Fortran '*'-comment prose (Reference BLAS): append a `*>` line after
    #     the last consecutive '*'-prefixed line at top.
    #
    # (e) No header: insert SPDX as the very first line, then a blank line.
    #
    # Files starting with `#!shebang` or a `#ifndef` guard — we always insert
    # the SPDX line above the guard but below any shebang.

    insert_at = 0
    has_shebang = lines and lines[0].startswith("#!")
    if has_shebang:
        insert_at = 1

    # (b) C-block comment opening at index `insert_at`.
    if insert_at < len(lines) and lines[insert_at].lstrip().startswith("/*"):
        for i in range(insert_at, len(lines)):
            if "*/" in lines[i]:
                insert_at = i + 1
                # Skip a single blank line after the block, if any.
                break
        new_block = spdx_line.decode()
        # We want SPDX as a // line after the */.
        return ("".join(lines[:insert_at]) + new_block + "".join(lines[insert_at:])).encode()

    # (a, c, d) Detect a top-of-file run of comment lines and insert after.
    end_of_block = insert_at
    if comment == "//":
        marker_prefixes = ("//",)
    elif comment == "#":
        marker_prefixes = ("#",)
    elif comment == "*>":
        # Fortran free-form file headers begin with `*` or `*>`.
        marker_prefixes = ("*",)
    else:
        marker_prefixes = (comment,)

    while end_of_block < len(lines):
        s = lines[end_of_block].lstrip()
        if any(s.startswith(p) for p in marker_prefixes):
            end_of_block += 1
            continue
        break

    if end_of_block > insert_at:
        # Append SPDX after the existing prose block.
        return (
            "".join(lines[:end_of_block])
            + spdx_line.decode()
            + "".join(lines[end_of_block:])
        ).encode()

    # (e) No header — insert at the top (after shebang if present), and
    # follow with a single blank line *unless* the file already starts with
    # one (otherwise clang-format collapses the duplicate).
    next_is_blank = (
        insert_at < len(lines) and lines[insert_at].strip() == ""
    )
    blank = "" if next_is_blank else eol
    return (
        "".join(lines[:insert_at])
        + spdx_line.decode()
        + blank
        + "".join(lines[insert_at:])
    ).encode()


# ---------------------------------------------------------------------------
# Driver
# ---------------------------------------------------------------------------

def tracked_files() -> Iterable[Path]:
    out = subprocess.check_output(
        ["git", "ls-files"], cwd=REPO_ROOT, text=True
    )
    for line in out.splitlines():
        if line:
            yield Path(line)


def main() -> int:
    p = argparse.ArgumentParser(description=__doc__)
    p.add_argument(
        "--check",
        action="store_true",
        help="Don't write; exit 1 if any file would change.",
    )
    p.add_argument(
        "--paths",
        nargs="*",
        help="Limit to these paths (relative to repo root). Default: all tracked.",
    )
    p.add_argument(
        "-v", "--verbose",
        action="store_true",
        help="Print every file decision (skip / classify / change).",
    )
    args = p.parse_args()

    if args.paths:
        targets = [Path(p) for p in args.paths]
    else:
        targets = list(tracked_files())

    changed = []
    for rel in targets:
        if is_skipped(rel):
            if args.verbose:
                print(f"[skip-rule] {rel}")
            continue

        full = REPO_ROOT / rel
        prefix = comment_prefix_for(rel, full)
        if prefix is None:
            if args.verbose:
                print(f"[skip-ext]  {rel}")
            continue
        try:
            content = full.read_bytes()
        except (FileNotFoundError, IsADirectoryError):
            continue

        spdx_id = classify(rel, content)
        new_content = insert_spdx(rel, content, spdx_id, prefix)
        if new_content is None:
            if args.verbose:
                print(f"[ok]        {rel}  ({spdx_id})")
            continue

        if args.check:
            print(f"[would-change] {rel}  ({spdx_id})")
            changed.append(rel)
            continue

        full.write_bytes(new_content)
        print(f"[changed]   {rel}  ({spdx_id})")
        changed.append(rel)

    if args.check and changed:
        print(f"\n{len(changed)} file(s) need SPDX headers.", file=sys.stderr)
        return 1
    if not args.check:
        print(f"\nUpdated {len(changed)} file(s).")
    return 0


if __name__ == "__main__":
    sys.exit(main())
