let env_log_level = match Sys.getenv_opt "LOG_LEVEL" with | None -> Some Logs.Warning | Some lvl -> ( match Logs.level_of_string lvl with Error _ -> None | Ok v -> v ) let run_solver name solver filepath = let content = Shared.File.read filepath in match solver content () with | Error msg -> Logs.app (fun m -> m "[%s] Err=%s" name msg) | Ok answer -> Logs.app (fun m -> m "[%s] ANSWER=%d" name answer) let run_day _ = function | 1 -> let filepath = "../.input/2025/day_01.txt" in run_solver "D01P01" Year2025.Day01.Part01.Solver.solve filepath ; run_solver "D01P02" Year2025.Day01.Part02.Solver.solve filepath ; 0 | 2 -> let filepath = "../.input/2025/day_02.txt" in run_solver "D02P01" Year2025.Day02.Part01.Solver.solve filepath ; run_solver "D02P02" Year2025.Day02.Part02.Solver.solve filepath ; 0 | 3 -> let filepath = "../.input/2025/day_03.txt" in run_solver "D03P01" Year2025.Day03.Part01.Solver.solve filepath ; run_solver "D03P02" Year2025.Day03.Part02.Solver.solve filepath ; 0 | 4 -> let filepath = "../.input/2025/day_04.txt" in run_solver "D04P01" Year2025.Day04.Part01.Solver.solve filepath ; run_solver "D04P02" Year2025.Day04.Part02.Solver.solve filepath ; 0 | 6 -> let filepath = "../.input/2025/day_06.txt" in run_solver "D06P01" Year2025.Day06.Part01.Solver.solve filepath ; run_solver "D06P02" Year2025.Day06.Part02.Solver.solve filepath ; 0 | _ -> failwith "day not implemented" (* Command line interface *) open Cmdliner let setup_log style_renderer = Fmt_tty.setup_std_outputs ?style_renderer () let setup_log_t = Term.(const setup_log $ Fmt_cli.style_renderer ()) let day_arg = let doc = "Day to run. MUST be in range of 1-12." in Arg.(value & pos 0 int 1 & info [] ~docv:"DAY" ~doc) let day_t = Term.(const run_day $ setup_log_t $ day_arg) let cmd = let info = Cmd.info "aoc" ~version:"0.1.0" in Cmd.v info day_t let run () = Cmd.eval' cmd let main () = let log_level = env_log_level in Logs.set_level log_level ; Logs.set_reporter (Logs_fmt.reporter ()) ; Logs.info (fun m -> m "Started application with LOG_LEVEL=%s" (Logs.level_to_string log_level) ) ; run () let () = if !Sys.interactive then () else exit (main ())