{-# OPTIONS_GHC -fno-warn-orphans #-}

module Data.GenValidity.Time.LocalTime where

import Data.Fixed
import Data.GenValidity
import Data.GenValidity.Time.Calendar ()
import Data.GenValidity.Time.Clock ()
import Data.Time.Format
import Data.Time.LocalTime
import Data.Validity.Time.LocalTime ()
import Test.QuickCheck

instance GenValid TimeZone where
  genValid :: Gen TimeZone
genValid = Int -> Bool -> String -> TimeZone
TimeZone forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. GenValid a => Gen a
genValid forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen String
genTimeZoneName
  shrinkValid :: TimeZone -> [TimeZone]
shrinkValid (TimeZone Int
m Bool
so String
n) =
    [Int -> Bool -> String -> TimeZone
TimeZone Int
m' Bool
so' String
n' | (Int
m', Bool
so', String
n') <- forall a. GenValid a => a -> [a]
shrinkValid (Int
m, Bool
so, String
n)]

genTimeZoneName :: Gen String
genTimeZoneName :: Gen String
genTimeZoneName =
  forall a. [(Int, Gen a)] -> Gen a
frequency
    [ (Int
1, forall (f :: * -> *) a. Applicative f => a -> f a
pure String
""),
      ( Int
4, -- Any three characters
        (:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid
          forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure []))
      ),
      ( Int
4, -- A +HHMM string
        (:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. [a] -> Gen a
elements [Char
'-', Char
'+']
          forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ( forall t. FormatTime t => TimeLocale -> String -> t -> String
formatTime TimeLocale
defaultTimeLocale String
"%H%M"
                  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> Int -> Pico -> TimeOfDay
TimeOfDay forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
23) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
59) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure Pico
0)
              )
      ),
      (Int
1, forall a. GenValid a => Gen a
genValid)
    ]

instance GenValid TimeOfDay where
  genValid :: Gen TimeOfDay
genValid =
    Int -> Int -> Pico -> TimeOfDay
TimeOfDay forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
23)) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
59))
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall k (a :: k). Integer -> Fixed a
MkFixed forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => (a, a) -> Gen a
choose (Integer
0, Integer
60999999999999))
  shrinkValid :: TimeOfDay -> [TimeOfDay]
shrinkValid (TimeOfDay Int
h Int
m Pico
s) = do
    (Int
h', Int
m', Pico
s') <-
      forall a b c.
(a -> [a]) -> (b -> [b]) -> (c -> [c]) -> (a, b, c) -> [(a, b, c)]
shrinkTriple
        (forall a. (a -> Bool) -> [a] -> [a]
filter (\Int
hh -> Int
0 forall a. Ord a => a -> a -> Bool
<= Int
hh Bool -> Bool -> Bool
&& Int
hh forall a. Ord a => a -> a -> Bool
< Int
24) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. GenValid a => a -> [a]
shrinkValid)
        (forall a. (a -> Bool) -> [a] -> [a]
filter (\Int
mm -> Int
0 forall a. Ord a => a -> a -> Bool
<= Int
mm Bool -> Bool -> Bool
&& Int
mm forall a. Ord a => a -> a -> Bool
< Int
60) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. GenValid a => a -> [a]
shrinkValid)
        (forall a. (a -> Bool) -> [a] -> [a]
filter (\Pico
ss -> Pico
0 forall a. Ord a => a -> a -> Bool
<= Pico
ss Bool -> Bool -> Bool
&& Pico
ss forall a. Ord a => a -> a -> Bool
< Pico
61) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. GenValid a => a -> [a]
shrinkValid)
        (Int
h, Int
m, Pico
s)
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> Int -> Pico -> TimeOfDay
TimeOfDay Int
h' Int
m' Pico
s')

instance GenValid LocalTime where
  genValid :: Gen LocalTime
genValid = Day -> TimeOfDay -> LocalTime
LocalTime forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. GenValid a => Gen a
genValid
  shrinkValid :: LocalTime -> [LocalTime]
shrinkValid (LocalTime Day
d TimeOfDay
tod) =
    [Day -> TimeOfDay -> LocalTime
LocalTime Day
d' TimeOfDay
tod' | (Day
d', TimeOfDay
tod') <- forall a. GenValid a => a -> [a]
shrinkValid (Day
d, TimeOfDay
tod)]

instance GenValid ZonedTime where
  genValid :: Gen ZonedTime
genValid = LocalTime -> TimeZone -> ZonedTime
ZonedTime forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. GenValid a => Gen a
genValid
  shrinkValid :: ZonedTime -> [ZonedTime]
shrinkValid (ZonedTime LocalTime
lt TimeZone
tz) =
    [LocalTime -> TimeZone -> ZonedTime
ZonedTime LocalTime
lt' TimeZone
tz' | (LocalTime
lt', TimeZone
tz') <- forall a. GenValid a => a -> [a]
shrinkValid (LocalTime
lt, TimeZone
tz)]

instance GenValid CalendarDiffTime where
  genValid :: Gen CalendarDiffTime
genValid = Integer -> NominalDiffTime -> CalendarDiffTime
CalendarDiffTime forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. GenValid a => Gen a
genValid
  shrinkValid :: CalendarDiffTime -> [CalendarDiffTime]
shrinkValid (CalendarDiffTime Integer
ms NominalDiffTime
t) =
    [Integer -> NominalDiffTime -> CalendarDiffTime
CalendarDiffTime Integer
ms' NominalDiffTime
t' | (Integer
ms', NominalDiffTime
t') <- forall a. GenValid a => a -> [a]
shrinkValid (Integer
ms, NominalDiffTime
t)]