{-# LANGUAGE DataKinds      #-}
{-# LANGUAGE KindSignatures #-}

module Haspara.Internal.FXQuoteDatabase where

import qualified Data.HashMap.Strict       as HM
import           GHC.TypeLits              (KnownNat, Nat)
import           Haspara.Internal.Currency (CurrencyPair)
import           Haspara.Internal.Date     (Date, addDays)
import           Haspara.Internal.FXQuote  (FXQuote)


type FXQuoteDatabase (n :: Nat) = HM.HashMap CurrencyPair (FXQuotePairDatabase n)


data FXQuotePairDatabase (n :: Nat) = FXQuotePairDatabase
  { FXQuotePairDatabase n -> CurrencyPair
fxQuotePairDatabasePair  :: !CurrencyPair
  , FXQuotePairDatabase n -> HashMap Date (FXQuote n)
fxQuotePairDatabaseTable :: !(HM.HashMap Date (FXQuote n))
  , FXQuotePairDatabase n -> Date
fxQuotePairDatabaseSince :: !Date
  , FXQuotePairDatabase n -> Date
fxQuotePairDatabaseUntil :: !Date
  }


findFXQuote :: KnownNat n => FXQuoteDatabase n -> CurrencyPair -> Date -> Maybe (FXQuote n)
findFXQuote :: FXQuoteDatabase n -> CurrencyPair -> Date -> Maybe (FXQuote n)
findFXQuote FXQuoteDatabase n
db CurrencyPair
cp Date
d = case CurrencyPair -> FXQuoteDatabase n -> Maybe (FXQuotePairDatabase n)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HM.lookup CurrencyPair
cp FXQuoteDatabase n
db of
  Maybe (FXQuotePairDatabase n)
Nothing  -> Maybe (FXQuote n)
forall a. Maybe a
Nothing
  Just FXQuotePairDatabase n
pdb -> Date -> FXQuotePairDatabase n -> Maybe (FXQuote n)
forall (n :: Nat).
KnownNat n =>
Date -> FXQuotePairDatabase n -> Maybe (FXQuote n)
findFXQuoteAux Date
d FXQuotePairDatabase n
pdb


findFXQuoteAux :: KnownNat n => Date -> FXQuotePairDatabase n -> Maybe (FXQuote n)
findFXQuoteAux :: Date -> FXQuotePairDatabase n -> Maybe (FXQuote n)
findFXQuoteAux Date
d FXQuotePairDatabase n
db
  | Date
d Date -> Date -> Bool
forall a. Ord a => a -> a -> Bool
< FXQuotePairDatabase n -> Date
forall (n :: Nat). FXQuotePairDatabase n -> Date
fxQuotePairDatabaseSince FXQuotePairDatabase n
db = Maybe (FXQuote n)
forall a. Maybe a
Nothing
  | Bool
otherwise = case Date -> HashMap Date (FXQuote n) -> Maybe (FXQuote n)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HM.lookup Date
d (FXQuotePairDatabase n -> HashMap Date (FXQuote n)
forall (n :: Nat).
FXQuotePairDatabase n -> HashMap Date (FXQuote n)
fxQuotePairDatabaseTable FXQuotePairDatabase n
db) of
      Maybe (FXQuote n)
Nothing -> Date -> FXQuotePairDatabase n -> Maybe (FXQuote n)
forall (n :: Nat).
KnownNat n =>
Date -> FXQuotePairDatabase n -> Maybe (FXQuote n)
findFXQuoteAux (Integer -> Date -> Date
addDays (-Integer
1) Date
d) FXQuotePairDatabase n
db
      Just FXQuote n
fx -> FXQuote n -> Maybe (FXQuote n)
forall a. a -> Maybe a
Just FXQuote n
fx