#!/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
- netlib Reference-BLAS / LAPACK files         -> BSD-3-Clause-Open-MPI
- 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"

# netlib Reference-BLAS / LAPACK files. LAPACK's LICENSE is BSD-3-Clause plus an IP disclaimer,
# i.e. BSD-3-Clause-Open-MPI. These files carry no Copyright line, so the holders named in that
# LICENSE are tagged rather than The Eigen Authors.
REFBLAS_MARKERS = (
    b"Reference BLAS is a software package",
    b"LAPACK is a software package provided by Univ. of Tennessee",
)
NETLIB_COPYRIGHT_HOLDERS = (
    "The University of Tennessee and The University of Tennessee Research Foundation",
    "The University of California Berkeley",
    "The University of Colorado Denver",
)

# 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-Open-MPI"
    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`, `contrib/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] in ("contrib", "unsupported")
        and parts[1] == "Eigen"
        and parts[-1][:1].isupper()
    ):
        # contrib/Eigen/Tensor (real), unsupported/Eigen/Tensor (legacy shim), ...
        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:
        is_netlib = spdx_id == "BSD-3-Clause-Open-MPI"
        for holder in NETLIB_COPYRIGHT_HOLDERS if is_netlib else ("The Eigen Authors",):
            spdx_lines.append(f"{comment} SPDX-FileCopyrightText: {holder}{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())
