-- |
-- Module: Settei.Report
-- Description: Secret-safe data describing one resolution run.
module Settei.Report
  ( BranchTrace (..),
    Derivation (..),
    ResolutionNode (..),
    ResolutionOutcome (..),
    ResolutionReport (..),
    reportBranches,
    reportNodes,
  )
where

import Data.Generics.Labels ()
import Data.Map.Strict qualified as Map
import Settei.Key (Key)
import Settei.Origin (Origin)
import Settei.Prelude
import Settei.Provenance (ReportedValue)
import Settei.Setting (Sensitivity)

-- | What happened to a statically possible setting in this run.
data ResolutionOutcome
  = Resolved !ReportedValue
  | MissingValue
  | NotSelected
  deriving stock ((forall x. ResolutionOutcome -> Rep ResolutionOutcome x)
-> (forall x. Rep ResolutionOutcome x -> ResolutionOutcome)
-> Generic ResolutionOutcome
forall x. Rep ResolutionOutcome x -> ResolutionOutcome
forall x. ResolutionOutcome -> Rep ResolutionOutcome x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ResolutionOutcome -> Rep ResolutionOutcome x
from :: forall x. ResolutionOutcome -> Rep ResolutionOutcome x
$cto :: forall x. Rep ResolutionOutcome x -> ResolutionOutcome
to :: forall x. Rep ResolutionOutcome x -> ResolutionOutcome
Generic, ResolutionOutcome -> ResolutionOutcome -> Bool
(ResolutionOutcome -> ResolutionOutcome -> Bool)
-> (ResolutionOutcome -> ResolutionOutcome -> Bool)
-> Eq ResolutionOutcome
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ResolutionOutcome -> ResolutionOutcome -> Bool
== :: ResolutionOutcome -> ResolutionOutcome -> Bool
$c/= :: ResolutionOutcome -> ResolutionOutcome -> Bool
/= :: ResolutionOutcome -> ResolutionOutcome -> Bool
Eq, Int -> ResolutionOutcome -> ShowS
[ResolutionOutcome] -> ShowS
ResolutionOutcome -> String
(Int -> ResolutionOutcome -> ShowS)
-> (ResolutionOutcome -> String)
-> ([ResolutionOutcome] -> ShowS)
-> Show ResolutionOutcome
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ResolutionOutcome -> ShowS
showsPrec :: Int -> ResolutionOutcome -> ShowS
$cshow :: ResolutionOutcome -> String
show :: ResolutionOutcome -> String
$cshowList :: [ResolutionOutcome] -> ShowS
showList :: [ResolutionOutcome] -> ShowS
Show)

-- | A named default rule that produced a setting value.
data Derivation = Derivation
  { Derivation -> Text
rule :: !Text,
    Derivation -> Text
explanation :: !Text,
    Derivation -> [Key]
dependencies :: ![Key]
  }
  deriving stock ((forall x. Derivation -> Rep Derivation x)
-> (forall x. Rep Derivation x -> Derivation) -> Generic Derivation
forall x. Rep Derivation x -> Derivation
forall x. Derivation -> Rep Derivation x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Derivation -> Rep Derivation x
from :: forall x. Derivation -> Rep Derivation x
$cto :: forall x. Rep Derivation x -> Derivation
to :: forall x. Rep Derivation x -> Derivation
Generic, Derivation -> Derivation -> Bool
(Derivation -> Derivation -> Bool)
-> (Derivation -> Derivation -> Bool) -> Eq Derivation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Derivation -> Derivation -> Bool
== :: Derivation -> Derivation -> Bool
$c/= :: Derivation -> Derivation -> Bool
/= :: Derivation -> Derivation -> Bool
Eq, Int -> Derivation -> ShowS
[Derivation] -> ShowS
Derivation -> String
(Int -> Derivation -> ShowS)
-> (Derivation -> String)
-> ([Derivation] -> ShowS)
-> Show Derivation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Derivation -> ShowS
showsPrec :: Int -> Derivation -> ShowS
$cshow :: Derivation -> String
show :: Derivation -> String
$cshowList :: [Derivation] -> ShowS
showList :: [Derivation] -> ShowS
Show)

-- | One evaluated or skipped setting, keyed independently in the report map.
data ResolutionNode = ResolutionNode
  { ResolutionNode -> Key
key :: !Key,
    ResolutionNode -> Sensitivity
sensitivity :: !Sensitivity,
    ResolutionNode -> ResolutionOutcome
outcome :: !ResolutionOutcome,
    ResolutionNode -> Maybe Origin
origin :: !(Maybe Origin),
    ResolutionNode -> [Origin]
shadowed :: ![Origin],
    ResolutionNode -> Maybe Derivation
derivation :: !(Maybe Derivation)
  }
  deriving stock ((forall x. ResolutionNode -> Rep ResolutionNode x)
-> (forall x. Rep ResolutionNode x -> ResolutionNode)
-> Generic ResolutionNode
forall x. Rep ResolutionNode x -> ResolutionNode
forall x. ResolutionNode -> Rep ResolutionNode x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ResolutionNode -> Rep ResolutionNode x
from :: forall x. ResolutionNode -> Rep ResolutionNode x
$cto :: forall x. Rep ResolutionNode x -> ResolutionNode
to :: forall x. Rep ResolutionNode x -> ResolutionNode
Generic, ResolutionNode -> ResolutionNode -> Bool
(ResolutionNode -> ResolutionNode -> Bool)
-> (ResolutionNode -> ResolutionNode -> Bool) -> Eq ResolutionNode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ResolutionNode -> ResolutionNode -> Bool
== :: ResolutionNode -> ResolutionNode -> Bool
$c/= :: ResolutionNode -> ResolutionNode -> Bool
/= :: ResolutionNode -> ResolutionNode -> Bool
Eq, Int -> ResolutionNode -> ShowS
[ResolutionNode] -> ShowS
ResolutionNode -> String
(Int -> ResolutionNode -> ShowS)
-> (ResolutionNode -> String)
-> ([ResolutionNode] -> ShowS)
-> Show ResolutionNode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ResolutionNode -> ShowS
showsPrec :: Int -> ResolutionNode -> ShowS
$cshow :: ResolutionNode -> String
show :: ResolutionNode -> String
$cshowList :: [ResolutionNode] -> ShowS
showList :: [ResolutionNode] -> ShowS
Show)

-- | Whether one selective branch was evaluated for this run.
data BranchTrace = BranchTrace
  { BranchTrace -> [Key]
dependencies :: ![Key],
    BranchTrace -> [Key]
settings :: ![Key],
    BranchTrace -> Bool
selected :: !Bool
  }
  deriving stock ((forall x. BranchTrace -> Rep BranchTrace x)
-> (forall x. Rep BranchTrace x -> BranchTrace)
-> Generic BranchTrace
forall x. Rep BranchTrace x -> BranchTrace
forall x. BranchTrace -> Rep BranchTrace x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. BranchTrace -> Rep BranchTrace x
from :: forall x. BranchTrace -> Rep BranchTrace x
$cto :: forall x. Rep BranchTrace x -> BranchTrace
to :: forall x. Rep BranchTrace x -> BranchTrace
Generic, BranchTrace -> BranchTrace -> Bool
(BranchTrace -> BranchTrace -> Bool)
-> (BranchTrace -> BranchTrace -> Bool) -> Eq BranchTrace
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BranchTrace -> BranchTrace -> Bool
== :: BranchTrace -> BranchTrace -> Bool
$c/= :: BranchTrace -> BranchTrace -> Bool
/= :: BranchTrace -> BranchTrace -> Bool
Eq, Int -> BranchTrace -> ShowS
[BranchTrace] -> ShowS
BranchTrace -> String
(Int -> BranchTrace -> ShowS)
-> (BranchTrace -> String)
-> ([BranchTrace] -> ShowS)
-> Show BranchTrace
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BranchTrace -> ShowS
showsPrec :: Int -> BranchTrace -> ShowS
$cshow :: BranchTrace -> String
show :: BranchTrace -> String
$cshowList :: [BranchTrace] -> ShowS
showList :: [BranchTrace] -> ShowS
Show)

-- | Complete, secret-safe trace for one resolution attempt.
data ResolutionReport = ResolutionReport
  { ResolutionReport -> Map Key ResolutionNode
nodes :: !(Map Key ResolutionNode),
    ResolutionReport -> [BranchTrace]
branches :: ![BranchTrace]
  }
  deriving stock ((forall x. ResolutionReport -> Rep ResolutionReport x)
-> (forall x. Rep ResolutionReport x -> ResolutionReport)
-> Generic ResolutionReport
forall x. Rep ResolutionReport x -> ResolutionReport
forall x. ResolutionReport -> Rep ResolutionReport x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ResolutionReport -> Rep ResolutionReport x
from :: forall x. ResolutionReport -> Rep ResolutionReport x
$cto :: forall x. Rep ResolutionReport x -> ResolutionReport
to :: forall x. Rep ResolutionReport x -> ResolutionReport
Generic, ResolutionReport -> ResolutionReport -> Bool
(ResolutionReport -> ResolutionReport -> Bool)
-> (ResolutionReport -> ResolutionReport -> Bool)
-> Eq ResolutionReport
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ResolutionReport -> ResolutionReport -> Bool
== :: ResolutionReport -> ResolutionReport -> Bool
$c/= :: ResolutionReport -> ResolutionReport -> Bool
/= :: ResolutionReport -> ResolutionReport -> Bool
Eq, Int -> ResolutionReport -> ShowS
[ResolutionReport] -> ShowS
ResolutionReport -> String
(Int -> ResolutionReport -> ShowS)
-> (ResolutionReport -> String)
-> ([ResolutionReport] -> ShowS)
-> Show ResolutionReport
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ResolutionReport -> ShowS
showsPrec :: Int -> ResolutionReport -> ShowS
$cshow :: ResolutionReport -> String
show :: ResolutionReport -> String
$cshowList :: [ResolutionReport] -> ShowS
showList :: [ResolutionReport] -> ShowS
Show)

-- | Return resolution nodes in stable key order.
reportNodes :: ResolutionReport -> [ResolutionNode]
reportNodes :: ResolutionReport -> [ResolutionNode]
reportNodes ResolutionReport
value = ResolutionReport
value ResolutionReport
-> Getting [ResolutionNode] ResolutionReport [ResolutionNode]
-> [ResolutionNode]
forall s a. s -> Getting a s a -> a
^. (Map Key ResolutionNode
 -> Const [ResolutionNode] (Map Key ResolutionNode))
-> ResolutionReport -> Const [ResolutionNode] ResolutionReport
#nodes ((Map Key ResolutionNode
  -> Const [ResolutionNode] (Map Key ResolutionNode))
 -> ResolutionReport -> Const [ResolutionNode] ResolutionReport)
-> (([ResolutionNode] -> Const [ResolutionNode] [ResolutionNode])
    -> Map Key ResolutionNode
    -> Const [ResolutionNode] (Map Key ResolutionNode))
-> Getting [ResolutionNode] ResolutionReport [ResolutionNode]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map Key ResolutionNode -> [ResolutionNode])
-> ([ResolutionNode] -> Const [ResolutionNode] [ResolutionNode])
-> Map Key ResolutionNode
-> Const [ResolutionNode] (Map Key ResolutionNode)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to Map Key ResolutionNode -> [ResolutionNode]
forall k a. Map k a -> [a]
Map.elems

-- | Return branch decisions in evaluation order.
reportBranches :: ResolutionReport -> [BranchTrace]
reportBranches :: ResolutionReport -> [BranchTrace]
reportBranches ResolutionReport
value = ResolutionReport
value ResolutionReport
-> Getting [BranchTrace] ResolutionReport [BranchTrace]
-> [BranchTrace]
forall s a. s -> Getting a s a -> a
^. Getting [BranchTrace] ResolutionReport [BranchTrace]
#branches