module Aoc where

import Control.Exception (assert, throwIO)
import Control.Monad.IO.Class (liftIO)

import System.IO

type Day = Int

input :: Int -> IO String
input day = readFile filepath
  where
    filepath = "inputs/day" ++ show day ++ ".txt"

sample :: Int -> IO String
sample day = readFile filepath
  where
    filepath = "inputs/day" ++ show day ++ "-sample.txt"

run :: (Eq a, Show a) => String -> Maybe a -> (String -> a) -> IO ()
run content solution f = do
  if calculated == solution
      then print calculated
      else hPutStr stderr $ "Incorrect: got '" ++ show calculated ++ "' expecting '" ++ show solution ++ "'\n"
  where
    calculated = Just $ f content

data Puzzle = Sample | Puzzle | AllPuzzles

data Part = Part1 | Part2 | AllParts

aoc :: Int -> (String -> Int) -> (String -> Int) -> Puzzle -> Part -> IO ()
aoc day part1 part2 AllPuzzles AllParts = do
  let run = aoc day part1 part2
  run AllPuzzles Part1
  run AllPuzzles Part2
aoc day part1 part2 AllPuzzles Part1 = do
  let run = aoc day part1 part2
  run Sample Part1
  run Puzzle Part1
aoc day part1 part2 AllPuzzles Part2 = do
  let run = aoc day part1 part2
  run Sample Part2
  run Puzzle Part2
aoc day part1 part2 Sample AllParts = do
  let run = aoc day part1 part2
  run Sample Part1
  run Sample Part2
aoc day part1 part2 Puzzle AllParts = do
  let run = aoc day part1 part2
  run Puzzle Part1
  run Puzzle Part2
aoc day part1 part2 Sample Part1 = do
  let run = aoc day part1 part2
  undefined
aoc day part1 part2 Sample Part2 = do
  let run = aoc day part1 part2
  undefined
aoc day part1 part2 Puzzle Part1 = do
  let run = aoc day part1 part2
  undefined
aoc day part1 part2 Puzzle Part2 = do
  let run = aoc day part1 part2
  undefined