from __future__ import annotations

import argparse
import sys

from ._fp_checker import run_cli


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="fp-checker",
        description="Check Python code for functional-programming-oriented rule violations.",
        epilog=(
            "Examples:\n"
            "  fp-checker check src\n"
            "  fp-checker check src --format json\n"
            "  fp-checker check src --fail-on error\n"
            "  fp-checker check . --config .fp-checker.toml\n"
        ),
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    subparsers = parser.add_subparsers(dest="command", required=True)

    check = subparsers.add_parser(
        "check",
        help="Check a file or directory.",
        description="Check a Python file or directory and print the report.",
        epilog=(
            "Examples:\n"
            "  fp-checker check src\n"
            "  fp-checker check src --format json\n"
            "  fp-checker check src --rule direct_io,non_deterministic_use\n"
            "  fp-checker check . --config .fp-checker.toml --rule no_eval\n"
        ),
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    check.add_argument("path")
    check.add_argument("--format", choices=["text", "json", "sarif"])
    check.add_argument("--include", action="append", default=[])
    check.add_argument("--exclude", action="append", default=[])
    check.add_argument("--fail-on", choices=["info", "warning", "error"])
    check.add_argument("--rule", action="append", default=[])
    check.add_argument("--ignore-decorator-name")
    check.add_argument("--config")
    return parser


def parse_csv_options(values: list[str]) -> list[str] | None:
    parsed = [item for value in values for item in value.split(",") if item]
    return parsed or None


def write_line(stream: object, text: str) -> None:
    writable = stream
    writable.write(text)
    if not text.endswith("\n"):
        writable.write("\n")


def main() -> int:
    parser = build_parser()
    args = parser.parse_args()

    if args.command != "check":
        parser.error(f"unsupported command: {args.command}")

    try:
        output, exit_code = run_cli(
            args.path,
            format=args.format,
            fail_on=args.fail_on,
            include=parse_csv_options(args.include),
            exclude=parse_csv_options(args.exclude),
            rule=parse_csv_options(args.rule),
            ignore_decorator_name=args.ignore_decorator_name,
            config=args.config,
        )
    except Exception as error:  # pragma: no cover - exercised via installed CLI smoke test
        write_line(sys.stderr, str(error))
        return 2

    write_line(sys.stdout, output)
    return exit_code


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