packages feed

casa-reoc-0.1.0.0: src/ReOC/Personnel.hs

{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wall #-}

{- | The holders of the key positions of a ReOC. A position held by the holder
of another position refers to that position ('CRPIsCEO', 'MCIsCRP', ...), so
each holder is found by following those references.
-}
module ReOC.Personnel (
  nominatedCEO,
  nominatedCRP,
  nominatedMC,
  nominatedCRI,
  keyPositions,
  holders,
  soleHolder,
) where

import Control.Lens (cloneLens, view)
import Data.List (nub)
import Data.Text (Text)
import ReOC.Model

-- | The nominated CEO.
nominatedCEO :: KeyPersonnel -> Nominee
nominatedCEO =
  view (cloneLens (chiefExecutive . nominee))

-- | The nominated chief remote pilot.
nominatedCRP :: KeyPersonnel -> Nominee
nominatedCRP k =
  case view (cloneLens (chiefPilot . crpNominee)) k of
    CRPIsCEO -> nominatedCEO k
    CRPNominated n -> n

-- | The nominated maintenance controller.
nominatedMC :: KeyPersonnel -> Nominee
nominatedMC k =
  case view (cloneLens mcNominee) k of
    MCIsCEO -> nominatedCEO k
    MCIsCRP -> nominatedCRP k
    MCNominated n -> n

-- | The nominated chief RePL instructor.
nominatedCRI :: KeyPersonnel -> TrainingMaterial -> Nominee
nominatedCRI k t =
  case view (cloneLens criNominee) t of
    CRIIsCEO -> nominatedCEO k
    CRIIsCRP -> nominatedCRP k
    CRIIsMC -> nominatedMC k
    CRINominated n -> n

{- | The key positions of a ReOC, in the order CEO, chief remote pilot,
maintenance controller and chief RePL instructor (if RePL training is
conducted): each with its abbreviation, its title and its holder.
-}
keyPositions :: ReOC -> [(Text, Text, Nominee)]
keyPositions r =
  let k = view (cloneLens (operator . keyPersonnel)) r
   in [ ("CEO", "chief executive officer", nominatedCEO k)
      , ("CRP", "chief remote pilot", nominatedCRP k)
      , ("MC", "maintenance controller", nominatedMC k)
      ]
        <> maybe [] (\t -> [("CRI", "chief RePL instructor", nominatedCRI k t)]) (view (cloneLens maybeTrainingMaterial) r)

-- | Each holder of a key position, once, with the abbreviations of the positions they hold.
holders :: ReOC -> [(Nominee, [Text])]
holders r =
  let ps = keyPositions r
   in [(n, [a | (a, _, m) <- ps, m == n]) | n <- nub [m | (_, _, m) <- ps]]

-- | The holder of every key position, if one person holds them all.
soleHolder :: ReOC -> Maybe Nominee
soleHolder r =
  case holders r of
    [(n, _)] -> Just n
    _ -> Nothing