"""Command-line entry point: `mbc build script.mb -o script.hex`.

Wires the pipeline together. `build` will raise NotImplementedError today
(parser and codegen are unfinished) -- that's expected; this exists so the
plumbing and error reporting are in place as each stage gets built out.
"""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

from . import __version__
from .codegen import generate_bytecode
from .hexfile import write_intel_hex
from .lexer import tokenize
from .parser import parse
from .preprocessor import expand_macros


def build(source_path: Path, output_path: Path) -> None:
    source = source_path.read_text()
    tokens = expand_macros(tokenize(source))
    program = parse(tokens)
    bytecode = generate_bytecode(program)
    output_path.write_text(write_intel_hex(bytecode))


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(prog="mbc", description="Roboteq MicroBasic compiler")
    parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
    sub = parser.add_subparsers(dest="command", required=True)

    build_p = sub.add_parser("build", help="Compile a .mb script to Intel HEX")
    build_p.add_argument("source", type=Path, help="Path to .mb source file")
    build_p.add_argument("-o", "--output", type=Path, help="Output .hex path (default: alongside source)")

    args = parser.parse_args(argv)

    if args.command == "build":
        output_path = args.output or args.source.with_suffix(".hex")
        try:
            build(args.source, output_path)
        except NotImplementedError as exc:
            print(f"error: {exc}", file=sys.stderr)
            return 1
        except Exception as exc:  # noqa: BLE001 -- top-level CLI error boundary
            print(f"error: {exc}", file=sys.stderr)
            return 1
        print(f"wrote {output_path}")
        return 0

    return 1


if __name__ == "__main__":
    raise SystemExit(main())
