{-# LANGUAGE OverloadedStrings #-}

module Jenga.Stack
  ( StackConfig (..)
  , StackExtraDep (..)
  , readStackConfig
  ) where

import           Data.Aeson (FromJSON (..), Value (..), (.:))
import           Data.Aeson.Types (typeMismatch)

import qualified Data.List as DL
import           Data.Monoid ((<>))

import           Data.Text (Text)
import qualified Data.Text as T
import           Data.Yaml (ParseException, Parser)
import qualified Data.Yaml as Y


data StackConfig = StackConfig
  { stackResolver :: !Text
  , stackExtraDeps :: ![StackExtraDep]
  }
  deriving (Eq, Show)

instance FromJSON StackConfig where
  parseJSON (Object v) = StackConfig
        <$> v .: "resolver"
        <*> v .: "extra-deps"

  parseJSON invalid = typeMismatch "StackConfig" invalid


data StackExtraDep
  = StackExtraDep !Text !Text
  deriving (Eq, Show)

instance FromJSON StackExtraDep where
  parseJSON (String s) = parseStackExtraDep s
  parseJSON invalid = typeMismatch "StackExtraDep" invalid

parseStackExtraDep :: Text -> Parser StackExtraDep
parseStackExtraDep str = do
  -- Extra-deps are of the form 'packageMame-version' where packageName itself
  -- may have a dash in it.
  let xs = T.splitOn "-" str
  if DL.length xs >= 2
    then pure $ StackExtraDep (T.intercalate "-" $ init xs) (last xs)
    else fail $ "Can't find version number in extra-dep : " <> T.unpack str

readStackConfig :: IO (Either ParseException StackConfig)
readStackConfig = Y.decodeFileEither stackYamlFile


stackYamlFile :: FilePath
stackYamlFile = "stack.yaml"