{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE QuasiQuotes                #-}

module Data.KeyStore.Types.UTC (UTC(..)) where

import           Data.Aeson
import           Data.API.JSON
import           Data.Time
import           Text.RE.Replace
import           Text.RE.TDFA.String


-- | package time has some variation in the formatting of second fractions
-- in %Q (http://hackage.haskell.org/package/time-1.8.0.2/changelog) so we
-- we will standardise on ".xxx"
newtype UTC = UTC { _UTC :: UTCTime }
  deriving (Eq,Show)


instance ToJSON UTC where
  toJSON = toJSON . formatUTC

instance FromJSON UTC where
  parseJSON = fmap UTC . parseJSON

instance FromJSONWithErrs UTC where
  parseJSONWithErrs = fmap UTC . parseJSONWithErrs


formatUTC :: UTC -> String
formatUTC (UTC u) = cleanup $ formatTime defaultTimeLocale fmt u
  where
    fmt = iso8601DateFormat $ Just "%H:%M:%S%QZ"

cleanup :: String -> String
cleanup s = case (captureTextMaybe [cp|u|] mtch,captureTextMaybe [cp|q|] mtch) of
    (Just u,Nothing) -> u ++ ".000Z"
    (Just u,Just q ) -> u ++ "." ++ rjust q ++ "Z"
    _ -> s
  where
    mtch = s ?=~ [re|^${u}([T0-9:-]+)(.${q}([0-9]*))?Z$|]

    rjust ds = take 3 $ ds ++ "000"