module Composite.Aeson.DateTimeFormatUtils
  ( fixupTzIn, fixupTzOut, fixupMs
  ) where

import BasicPrelude
import Data.Char (isDigit)
import Data.Function (fix)

-- |Given a string, remove a trailing @Z@ (which is ISO8601 acceptable) and replace it with @+00:00@ (which is @ParseTime@ acceptable)
fixupTzIn :: String -> String
fixupTzIn s = maybe s ((++ "+00:00") . reverse) $ stripPrefix "Z"      (reverse s)

-- |Given a string, remove a trailing @+00:00@ (which @FormatTime@) and replace it with @Z@ (which is ISO8601 standard)
fixupTzOut :: String -> String
fixupTzOut s = maybe s ((++ "Z")      . reverse) $ stripPrefix "00:00+" (reverse s)

-- |Given a ISO8601-ish string generated by @FormatTime@ with @%Q@, generating between no decimal and 12 digits of decimal, normalize it to exactly
-- three digits.
--
-- E.g. from @2017-03-30T13:00:00Z@ generate @2017-03-30T13:00:00.000Z@, and from @2017-03-30T13:00:00.123456789Z@ generate @2017-03-30T12:00:00.123Z@
fixupMs :: String -> String
fixupMs (':':s10:s1:tzChar:rest) | tzChar == 'Z' || tzChar == '+' || tzChar == '-' =
  ':':s10:s1:'.':'0':'0':'0':tzChar:rest
fixupMs (':':s10:s1:'.':digitsAndRest) =
  let (digits, rest) = span isDigit digitsAndRest
      newDigits = take 3 (digits ++ fix ('0':))
  in ':':s10:s1:'.':(newDigits ++ rest)
fixupMs (c:cs) = c : fixupMs cs
fixupMs []     = []