module Network.HTTP2.Arch.Rate (
    Rate
  , newRate
  , getRate
  ) where

import Data.IORef
import Data.UnixTime

newtype Rate = Rate (IORef Counter)

data Counter = Counter Int UnixTime

newRate :: IO Rate
newRate :: IO Rate
newRate = do
    Counter
cntr <- Int -> UnixTime -> Counter
Counter Int
0 (UnixTime -> Counter) -> IO UnixTime -> IO Counter
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO UnixTime
getUnixTime
    IORef Counter -> Rate
Rate (IORef Counter -> Rate) -> IO (IORef Counter) -> IO Rate
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Counter -> IO (IORef Counter)
forall a. a -> IO (IORef a)
newIORef Counter
cntr

getRate :: Rate -> IO Int
getRate :: Rate -> IO Int
getRate (Rate IORef Counter
ref) = do
    Counter Int
n UnixTime
beg <- IORef Counter -> IO Counter
forall a. IORef a -> IO a
readIORef IORef Counter
ref
    UnixTime
cur <- IO UnixTime
getUnixTime
    if (UnixTime
cur UnixTime -> UnixTime -> UnixDiffTime
`diffUnixTime` UnixTime
beg) UnixDiffTime -> UnixDiffTime -> Bool
forall a. Ord a => a -> a -> Bool
> UnixDiffTime
1 then do
        let n' :: Int
n' = Int
1
        IORef Counter -> Counter -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Counter
ref (Counter -> IO ()) -> Counter -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> UnixTime -> Counter
Counter Int
n' UnixTime
cur
        Int -> IO Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
n'
      else do
        let n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
        IORef Counter -> Counter -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Counter
ref (Counter -> IO ()) -> Counter -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> UnixTime -> Counter
Counter Int
n' UnixTime
beg
        Int -> IO Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
n'