{-|
Module      : SimFin.Types.FiscalPeriod
Description : Types that describe a fiscal period.
Copyright   : (c) Owen Shepherd, 2022
License     : MIT
Maintainer  : owen@owen.cafe
-}

{-# LANGUAGE OverloadedStrings #-}

module SimFin.Types.FiscalPeriod
  ( FiscalPeriod(..)
  , fiscalPeriodParam
  ) where

import Data.Aeson
import Data.ByteString (ByteString)
import qualified Data.Text as T

-- | A fiscal period as understood by the SimFin API.

data FiscalPeriod = Q1 | Q2 | Q3 | Q4 | H1 | H2 | FullYear | FirstNineMonths | SixMonths
  deriving (FiscalPeriod -> FiscalPeriod -> Bool
(FiscalPeriod -> FiscalPeriod -> Bool)
-> (FiscalPeriod -> FiscalPeriod -> Bool) -> Eq FiscalPeriod
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FiscalPeriod -> FiscalPeriod -> Bool
$c/= :: FiscalPeriod -> FiscalPeriod -> Bool
== :: FiscalPeriod -> FiscalPeriod -> Bool
$c== :: FiscalPeriod -> FiscalPeriod -> Bool
Eq, Int -> FiscalPeriod -> ShowS
[FiscalPeriod] -> ShowS
FiscalPeriod -> String
(Int -> FiscalPeriod -> ShowS)
-> (FiscalPeriod -> String)
-> ([FiscalPeriod] -> ShowS)
-> Show FiscalPeriod
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FiscalPeriod] -> ShowS
$cshowList :: [FiscalPeriod] -> ShowS
show :: FiscalPeriod -> String
$cshow :: FiscalPeriod -> String
showsPrec :: Int -> FiscalPeriod -> ShowS
$cshowsPrec :: Int -> FiscalPeriod -> ShowS
Show)

instance FromJSON FiscalPeriod where
  parseJSON :: Value -> Parser FiscalPeriod
parseJSON = String
-> (Text -> Parser FiscalPeriod) -> Value -> Parser FiscalPeriod
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"FiscalPeriod" ((Text -> Parser FiscalPeriod) -> Value -> Parser FiscalPeriod)
-> (Text -> Parser FiscalPeriod) -> Value -> Parser FiscalPeriod
forall a b. (a -> b) -> a -> b
$ \Text
t -> case Text -> Text
T.toLower Text
t of
    Text
"q1" -> FiscalPeriod -> Parser FiscalPeriod
forall (f :: * -> *) a. Applicative f => a -> f a
pure FiscalPeriod
Q1
    Text
"q2" -> FiscalPeriod -> Parser FiscalPeriod
forall (f :: * -> *) a. Applicative f => a -> f a
pure FiscalPeriod
Q2
    Text
"q3" -> FiscalPeriod -> Parser FiscalPeriod
forall (f :: * -> *) a. Applicative f => a -> f a
pure FiscalPeriod
Q3
    Text
"q4" -> FiscalPeriod -> Parser FiscalPeriod
forall (f :: * -> *) a. Applicative f => a -> f a
pure FiscalPeriod
Q4
    Text
"h1" -> FiscalPeriod -> Parser FiscalPeriod
forall (f :: * -> *) a. Applicative f => a -> f a
pure FiscalPeriod
H1
    Text
"h2" -> FiscalPeriod -> Parser FiscalPeriod
forall (f :: * -> *) a. Applicative f => a -> f a
pure FiscalPeriod
H2
    Text
"fy" -> FiscalPeriod -> Parser FiscalPeriod
forall (f :: * -> *) a. Applicative f => a -> f a
pure FiscalPeriod
FullYear
    Text
"9m" -> FiscalPeriod -> Parser FiscalPeriod
forall (f :: * -> *) a. Applicative f => a -> f a
pure FiscalPeriod
FirstNineMonths
    Text
"6m" -> FiscalPeriod -> Parser FiscalPeriod
forall (f :: * -> *) a. Applicative f => a -> f a
pure FiscalPeriod
SixMonths
    Text
_ -> String -> Parser FiscalPeriod
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid fiscal year string"

-- | Converts a fiscal period into a query string fragment as understood by the SimFin API.

fiscalPeriodParam :: FiscalPeriod -> ByteString
fiscalPeriodParam :: FiscalPeriod -> ByteString
fiscalPeriodParam FiscalPeriod
a = case FiscalPeriod
a of
  FiscalPeriod
Q1 -> ByteString
"q1"
  FiscalPeriod
Q2 -> ByteString
"q2"
  FiscalPeriod
Q3 -> ByteString
"q3"
  FiscalPeriod
Q4 -> ByteString
"q4"
  FiscalPeriod
H1 -> ByteString
"h1"
  FiscalPeriod
H2 -> ByteString
"h2"
  FiscalPeriod
FullYear-> ByteString
"fy"
  FiscalPeriod
FirstNineMonths -> ByteString
"9m"
  FiscalPeriod
SixMonths -> ByteString
"6m"