module Parser (parseNonogram) where

import NonogramTypes
import Data.List (isPrefixOf, uncons)
import Data.List.Split (splitOn)
import Data.Maybe (mapMaybe)


-- Parse
parseNonogram :: FilePath -> IO Nonogram
parseNonogram path = do
  content <- lines <$> readFile path
  let titleLine   = extractValue "title" content
      heightLine  = read (extractValue "height" content) :: Int
      widthLine   = read (extractValue "width" content) :: Int
      rowsSection = extractSection "rows" "columns" content
      colsSection = extractSection "columns" "goal" content
      goalSection = extractValue "goal" content
      rowsHints   = parseHints rowsSection
      colsHints   = parseHints colsSection
  return Nonogram { title = titleLine, height = heightLine, width = widthLine, rows = rowsHints, columns = colsHints, goal = goalSection }


-- Extract value from key in file
extractValue :: String -> [String] -> String
extractValue key allLines =
  let matchingLines = [line | line <- allLines, key `isPrefixOf` line]
  in case uncons matchingLines of
       Just (matchingLine, _) -> unquote $ drop (length key + 1) matchingLine
       Nothing -> error $ "Key not found: " ++ key -- empty case
  where
    unquote s = filter (`notElem` "\"") s -- no quotes


-- Extract sections
extractSection :: String -> String -> [String] -> [String]
extractSection startKey endKey allLines =
  takeWhile (not . isPrefixOf endKey) . drop 1 . dropWhile (not . isPrefixOf startKey) $ allLines

-- Parse hints into list of lists of integers
parseHints :: [String] -> [[Int]]
parseHints = mapMaybe safeParseLine

-- Safe parsing of individual lines
safeParseLine :: String -> Maybe [Int]
safeParseLine line =
  if null line then Nothing
  else Just (map read $ splitOn "," line)



