#!/usr/bin/env python3
# ex: set filetype=python:

"""Common parsing code for xdrgen"""

import sys
from typing import Callable

from lark import Lark
from lark.exceptions import UnexpectedInput, UnexpectedToken, VisitError


# Set to True to emit annotation comments in generated source
annotate = False

# Set to True to emit enum value validation in decoders
enum_validation = True

# Map internal Lark token names to human-readable names
TOKEN_NAMES = {
    "__ANON_0": "identifier",
    "__ANON_1": "number",
    "SEMICOLON": "';'",
    "LBRACE": "'{'",
    "RBRACE": "'}'",
    "LPAR": "'('",
    "RPAR": "')'",
    "LSQB": "'['",
    "RSQB": "']'",
    "LESSTHAN": "'<'",
    "MORETHAN": "'>'",
    "EQUAL": "'='",
    "COLON": "':'",
    "COMMA": "','",
    "STAR": "'*'",
    "$END": "end of file",
}


class XdrParseError(Exception):
    """Raised when XDR parsing fails"""


def set_xdr_annotate(set_it: bool) -> None:
    """Set 'annotate' if --annotate was specified on the command line"""
    global annotate
    annotate = set_it


def get_xdr_annotate() -> bool:
    """Return True if --annotate was specified on the command line"""
    return annotate


def set_xdr_enum_validation(set_it: bool) -> None:
    """Set 'enum_validation' based on command line options"""
    global enum_validation
    enum_validation = set_it


def get_xdr_enum_validation() -> bool:
    """Return True when enum validation is enabled for decoder generation"""
    return enum_validation


def format_source_caret(line_text: str, column: int) -> list[str]:
    """Render an offending source line with a caret beneath a column.

    Args:
        line_text: The raw source line containing the error
        column: 1-based column of the offending token within line_text

    Returns:
        Output lines for the diagnostic: a blank separator, the source
        line with tabs expanded, and a caret aligned under the column.
    """
    expanded = line_text.expandtabs()
    caret = len(line_text[: column - 1].expandtabs())
    return ["", f"    {expanded}", f"    {' ' * caret}^"]


def make_error_handler(source: str, filename: str) -> Callable[[UnexpectedInput], bool]:
    """Create an error handler that reports the first parse error and aborts.

    Args:
        source: The XDR source text being parsed
        filename: The name of the file being parsed

    Returns:
        An error handler function for use with Lark's on_error parameter
    """
    lines = source.splitlines()

    def handle_parse_error(e: UnexpectedInput) -> bool:
        """Report a parse error with context and abort parsing"""
        line_num = e.line
        column = e.column
        line_text = lines[line_num - 1] if 0 < line_num <= len(lines) else ""

        # Build the error message
        msg_parts = [f"{filename}:{line_num}:{column}: parse error"]

        # Show what was found vs what was expected
        if isinstance(e, UnexpectedToken):
            token = e.token
            if token.type == "__ANON_0":
                found = f"identifier '{token.value}'"
            elif token.type == "__ANON_1":
                found = f"number '{token.value}'"
            else:
                found = f"'{token.value}'"
            msg_parts.append(f"Unexpected {found}")

            # Provide helpful expected tokens list
            expected = e.expected
            if expected:
                readable = [
                    TOKEN_NAMES.get(exp, exp.lower().replace("_", " "))
                    for exp in sorted(expected)
                ]
                if len(readable) == 1:
                    msg_parts.append(f"Expected {readable[0]}")
                elif len(readable) <= 4:
                    msg_parts.append(f"Expected one of: {', '.join(readable)}")
        else:
            msg_parts.append(str(e).split("\n")[0])

        # Show the offending line with a caret pointing to the error
        msg_parts.extend(format_source_caret(line_text, column))

        sys.stderr.write("\n".join(msg_parts) + "\n")
        raise XdrParseError()

    return handle_parse_error


def handle_transform_error(e: VisitError, source: str, filename: str) -> None:
    """Report a transform error with context.

    Args:
        e: The VisitError from Lark's transformer
        source: The XDR source text being parsed
        filename: The name of the file being parsed
    """
    lines = source.splitlines()

    # Extract position from the tree node if available
    line_num = 0
    column = 0
    if hasattr(e.obj, "meta") and e.obj.meta:
        line_num = e.obj.meta.line
        column = e.obj.meta.column

    line_text = lines[line_num - 1] if 0 < line_num <= len(lines) else ""

    # Build the error message
    msg_parts = [f"{filename}:{line_num}:{column}: semantic error"]

    # The original exception is typically a KeyError for undefined types
    if isinstance(e.orig_exc, KeyError):
        msg_parts.append(f"Undefined type '{e.orig_exc.args[0]}'")
    else:
        msg_parts.append(str(e.orig_exc))

    # Show the offending line with a caret pointing to the error
    if line_text:
        msg_parts.extend(format_source_caret(line_text, column))

    sys.stderr.write("\n".join(msg_parts) + "\n")


def handle_semantic_error(e, source: str, filename: str) -> None:
    """Report a semantic error (e.g., a duplicate name) with context.

    Args:
        e: The XdrSemanticError carrying message and source position
        source: The XDR source text being parsed
        filename: The name of the file being parsed
    """
    lines = source.splitlines()
    line_num = getattr(e, "line", 0)
    column = getattr(e, "column", 0)
    line_text = lines[line_num - 1] if 0 < line_num <= len(lines) else ""

    msg_parts = [f"{filename}:{line_num}:{column}: semantic error", e.message]
    if line_text:
        msg_parts.extend(format_source_caret(line_text, column))

    sys.stderr.write("\n".join(msg_parts) + "\n")


def xdr_parser() -> Lark:
    """Return a Lark parser instance configured with the XDR language grammar"""

    return Lark.open(
        "grammars/xdr.lark",
        rel_to=__file__,
        start="specification",
        debug=True,
        strict=True,
        propagate_positions=True,
        parser="lalr",
        lexer="contextual",
    )
