{-# LANGUAGE TemplateHaskell #-}

module Hydra.Data.DepositPeriod where

import Hydra.Prelude

import PlutusTx.Prelude qualified as Plutus

import Data.Ratio ((%))
import Data.Time (nominalDiffTimeToSeconds, secondsToNominalDiffTime)
import PlutusLedgerApi.V1.Time (DiffMilliSeconds)
import PlutusTx qualified

newtype DepositPeriod = UnsafeDepositPeriod {DepositPeriod -> DiffMilliSeconds
milliseconds :: DiffMilliSeconds}
  deriving stock ((forall x. DepositPeriod -> Rep DepositPeriod x)
-> (forall x. Rep DepositPeriod x -> DepositPeriod)
-> Generic DepositPeriod
forall x. Rep DepositPeriod x -> DepositPeriod
forall x. DepositPeriod -> Rep DepositPeriod x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. DepositPeriod -> Rep DepositPeriod x
from :: forall x. DepositPeriod -> Rep DepositPeriod x
$cto :: forall x. Rep DepositPeriod x -> DepositPeriod
to :: forall x. Rep DepositPeriod x -> DepositPeriod
Generic, DepositPeriod -> DepositPeriod -> Bool
(DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> Bool) -> Eq DepositPeriod
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DepositPeriod -> DepositPeriod -> Bool
== :: DepositPeriod -> DepositPeriod -> Bool
$c/= :: DepositPeriod -> DepositPeriod -> Bool
/= :: DepositPeriod -> DepositPeriod -> Bool
Eq, Eq DepositPeriod
Eq DepositPeriod =>
(DepositPeriod -> DepositPeriod -> Ordering)
-> (DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod -> DepositPeriod)
-> Ord DepositPeriod
DepositPeriod -> DepositPeriod -> Bool
DepositPeriod -> DepositPeriod -> Ordering
DepositPeriod -> DepositPeriod -> DepositPeriod
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: DepositPeriod -> DepositPeriod -> Ordering
compare :: DepositPeriod -> DepositPeriod -> Ordering
$c< :: DepositPeriod -> DepositPeriod -> Bool
< :: DepositPeriod -> DepositPeriod -> Bool
$c<= :: DepositPeriod -> DepositPeriod -> Bool
<= :: DepositPeriod -> DepositPeriod -> Bool
$c> :: DepositPeriod -> DepositPeriod -> Bool
> :: DepositPeriod -> DepositPeriod -> Bool
$c>= :: DepositPeriod -> DepositPeriod -> Bool
>= :: DepositPeriod -> DepositPeriod -> Bool
$cmax :: DepositPeriod -> DepositPeriod -> DepositPeriod
max :: DepositPeriod -> DepositPeriod -> DepositPeriod
$cmin :: DepositPeriod -> DepositPeriod -> DepositPeriod
min :: DepositPeriod -> DepositPeriod -> DepositPeriod
Ord, Int -> DepositPeriod -> ShowS
[DepositPeriod] -> ShowS
DepositPeriod -> String
(Int -> DepositPeriod -> ShowS)
-> (DepositPeriod -> String)
-> ([DepositPeriod] -> ShowS)
-> Show DepositPeriod
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DepositPeriod -> ShowS
showsPrec :: Int -> DepositPeriod -> ShowS
$cshow :: DepositPeriod -> String
show :: DepositPeriod -> String
$cshowList :: [DepositPeriod] -> ShowS
showList :: [DepositPeriod] -> ShowS
Show)
  deriving newtype (Integer -> DepositPeriod
DepositPeriod -> DepositPeriod
DepositPeriod -> DepositPeriod -> DepositPeriod
(DepositPeriod -> DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod)
-> (Integer -> DepositPeriod)
-> Num DepositPeriod
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: DepositPeriod -> DepositPeriod -> DepositPeriod
+ :: DepositPeriod -> DepositPeriod -> DepositPeriod
$c- :: DepositPeriod -> DepositPeriod -> DepositPeriod
- :: DepositPeriod -> DepositPeriod -> DepositPeriod
$c* :: DepositPeriod -> DepositPeriod -> DepositPeriod
* :: DepositPeriod -> DepositPeriod -> DepositPeriod
$cnegate :: DepositPeriod -> DepositPeriod
negate :: DepositPeriod -> DepositPeriod
$cabs :: DepositPeriod -> DepositPeriod
abs :: DepositPeriod -> DepositPeriod
$csignum :: DepositPeriod -> DepositPeriod
signum :: DepositPeriod -> DepositPeriod
$cfromInteger :: Integer -> DepositPeriod
fromInteger :: Integer -> DepositPeriod
Num, DepositPeriod -> DepositPeriod -> Bool
(DepositPeriod -> DepositPeriod -> Bool) -> Eq DepositPeriod
forall a. (a -> a -> Bool) -> Eq a
$c== :: DepositPeriod -> DepositPeriod -> Bool
== :: DepositPeriod -> DepositPeriod -> Bool
Plutus.Eq)

PlutusTx.unstableMakeIsData ''DepositPeriod

depositPeriodFromDiffTime :: NominalDiffTime -> DepositPeriod
depositPeriodFromDiffTime :: NominalDiffTime -> DepositPeriod
depositPeriodFromDiffTime = DiffMilliSeconds -> DepositPeriod
UnsafeDepositPeriod (DiffMilliSeconds -> DepositPeriod)
-> (NominalDiffTime -> DiffMilliSeconds)
-> NominalDiffTime
-> DepositPeriod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pico -> DiffMilliSeconds
forall b. Integral b => Pico -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Pico -> DiffMilliSeconds)
-> (NominalDiffTime -> Pico) -> NominalDiffTime -> DiffMilliSeconds
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pico -> Pico -> Pico
forall a. Num a => a -> a -> a
* Pico
1000) (Pico -> Pico)
-> (NominalDiffTime -> Pico) -> NominalDiffTime -> Pico
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NominalDiffTime -> Pico
nominalDiffTimeToSeconds

depositPeriodToDiffTime :: DepositPeriod -> NominalDiffTime
depositPeriodToDiffTime :: DepositPeriod -> NominalDiffTime
depositPeriodToDiffTime DepositPeriod
dp =
  Pico -> NominalDiffTime
secondsToNominalDiffTime (Pico -> NominalDiffTime) -> Pico -> NominalDiffTime
forall a b. (a -> b) -> a -> b
$ Rational -> Pico
forall a. Fractional a => Rational -> a
fromRational (DiffMilliSeconds -> Integer
forall a. Integral a => a -> Integer
toInteger (DepositPeriod -> DiffMilliSeconds
milliseconds DepositPeriod
dp) Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
1000)