{- |
Copyright : Flipstone Technology Partners 2023
License   : MIT
Stability : Stable

@since 1.0.0.0
-}
module Orville.PostgreSQL.Plan.Explanation
  ( Explanation
  , noExplanation
  , explainStep
  , explanationSteps
  )
where

{- |
 An 'Explanation' represents an example sequence of queries showing the steps
 would be executed by an Orville 'Orville.PostgreSQL.Plan.Operation.Operation'.

@since 1.0.0.0
-}
newtype Explanation
  = Explanation ([String] -> [String])

instance Semigroup Explanation where
  <> :: Explanation -> Explanation -> Explanation
(<>) = Explanation -> Explanation -> Explanation
appendExplanation

instance Monoid Explanation where
  mempty :: Explanation
mempty = Explanation
noExplanation

{- |
Appends two 'Explanation's with the steps from the first argument being shown
first.

@since 1.0.0.0
-}
appendExplanation :: Explanation -> Explanation -> Explanation
appendExplanation :: Explanation -> Explanation -> Explanation
appendExplanation (Explanation [String] -> [String]
front) (Explanation [String] -> [String]
back) =
  ([String] -> [String]) -> Explanation
Explanation ([String] -> [String]
front ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
back)

{- |
Constructs an empty 'Explanation'.

@since 1.0.0.0
-}
noExplanation :: Explanation
noExplanation :: Explanation
noExplanation =
  ([String] -> [String]) -> Explanation
Explanation [String] -> [String]
forall a. a -> a
id

{- |
Constructs an 'Explanation' with a single step.

@since 1.0.0.0
-}
explainStep :: String -> Explanation
explainStep :: String -> Explanation
explainStep String
str =
  ([String] -> [String]) -> Explanation
Explanation (String
str String -> [String] -> [String]
forall a. a -> [a] -> [a]
:)

{- |
Retrieves the steps contained in the 'Explanation'.

@since 1.0.0.0
-}
explanationSteps :: Explanation -> [String]
explanationSteps :: Explanation -> [String]
explanationSteps (Explanation [String] -> [String]
prependTo) =
  [String] -> [String]
prependTo []