from __future__ import annotations

import argparse
from pathlib import Path
from typing import Any

from setup import setup_macroenergy_jl
from setup.julia_setup import _jl

from .run_case import run_case


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="macroenergy-run-case",
        description="Run MacroEnergy.jl run_case from Python.",
    )
    parser.add_argument(
        "case_path",
        nargs="?",
        default=".",
        help="Path to case directory containing system data/settings.",
    )

    parser.add_argument("--setup-first", action="store_true", help="Run setup_macroenergy_jl() before run_case.")
    parser.add_argument("--url", default=None, help="Optional git URL used with --setup-first.")
    parser.add_argument("--rev", default=None, help="Optional git revision used with --setup-first.")

    parser.add_argument("--lazy-load", dest="lazy_load", action="store_true", default=True)
    parser.add_argument("--no-lazy-load", dest="lazy_load", action="store_false")

    parser.add_argument("--log-to-console", dest="log_to_console", action="store_true", default=True)
    parser.add_argument("--no-log-to-console", dest="log_to_console", action="store_false")

    parser.add_argument("--log-to-file", dest="log_to_file", action="store_true", default=True)
    parser.add_argument("--no-log-to-file", dest="log_to_file", action="store_false")

    parser.add_argument("--log-file-path", default=None, help="Optional log file path.")

    parser.add_argument(
        "--log-file-attribution",
        dest="log_file_attribution",
        action="store_true",
        default=True,
    )
    parser.add_argument(
        "--no-log-file-attribution",
        dest="log_file_attribution",
        action="store_false",
    )

    parser.add_argument(
        "--log-level",
        choices=["Debug", "Info", "Warn", "Error"],
        default=None,
        help="Optional Julia Logging level.",
    )

    return parser


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

    if args.setup_first:
        setup_macroenergy_jl(url=args.url, rev=args.rev)

    kwargs: dict[str, Any] = {
        "lazy_load": args.lazy_load,
        "log_to_console": args.log_to_console,
        "log_to_file": args.log_to_file,
        "log_file_attribution": args.log_file_attribution,
    }

    if args.log_file_path:
        kwargs["log_file_path"] = str(Path(args.log_file_path).resolve())

    if args.log_level:
        kwargs["log_level"] = _parse_log_level(args.log_level)

    systems, _solution = run_case(args.case_path, **kwargs)
    try:
        systems_count = len(systems)
    except Exception:
        systems_count = -1

    if systems_count >= 0:
        print(f"run_case completed: {systems_count} system(s) solved")
    else:
        print("run_case completed")

    return 0


def _parse_log_level(level: str) -> Any:
    jl = _jl()
    jl.log_level_name = level
    return jl.seval("using Logging; getproperty(Logging, Symbol(log_level_name))")


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