-- |
-- Module     : Simulation.Aivika.Trans.Results.Locale.Types
-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.1
--
-- The module defines basic definitions for localisation.
--
module Simulation.Aivika.Trans.Results.Locale.Types
       (-- * Basic Types
        ResultLocale,
        ResultLocalisation(..),
        ResultName,
        ResultDescription,
        UserDefinedResult(..),
        LocalisedResult(..),
        -- * Locale Codes
        russianResultLocale,
        englishResultLocale,
        -- * Localisations
        pathResultLocalisation,
        localisePathResultDescription,
        localisePathResultTitle,
        lookupResultLocalisation,
        -- * Unique Identifiers
        ResultId(..),
        -- * Utilities
        resultNameToTitle) where

import Data.Char
import Data.List
import qualified Data.Map as M

import Simulation.Aivika.Trans.Dynamics
import Simulation.Aivika.Trans.Statistics
import Simulation.Aivika.Trans.Statistics.Accumulator
import qualified Simulation.Aivika.Trans.Queue as Q
import qualified Simulation.Aivika.Trans.Queue.Infinite as IQ
import Simulation.Aivika.Trans.Arrival
import Simulation.Aivika.Trans.Server
import Simulation.Aivika.Trans.Activity
import Simulation.Aivika.Trans.Resource
import Simulation.Aivika.Trans.Operation

-- | A locale to output the simulation results.
--
-- Examples are: @\"ru\", @\"en\" etc.
type ResultLocale = String

-- | It localises the description and title of simulation results.
data ResultLocalisation =
  ResultLocalisation { ResultLocalisation -> ResultId -> ResultLocale
localiseResultDescription :: ResultId -> ResultDescription,
                       -- ^ Localise the description.
                       ResultLocalisation -> ResultId -> ResultLocale
localiseResultTitle :: ResultId -> ResultDescription
                       -- ^ Localise the title.
                     }

-- | It describes the user-defined simulation result.
data UserDefinedResult =
  UserDefinedResult { UserDefinedResult -> ResultLocale
userDefinedResultName :: ResultName,
                      -- ^ The user-defined result name.
                      UserDefinedResult -> ResultLocale
userDefinedResultDescription :: ResultDescription,
                      -- ^ The user-defined result description.
                      UserDefinedResult -> ResultLocale
userDefinedResultTitle :: ResultDescription
                      -- ^ The user-defined result title.
                    } deriving (UserDefinedResult -> UserDefinedResult -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UserDefinedResult -> UserDefinedResult -> Bool
$c/= :: UserDefinedResult -> UserDefinedResult -> Bool
== :: UserDefinedResult -> UserDefinedResult -> Bool
$c== :: UserDefinedResult -> UserDefinedResult -> Bool
Eq, Eq UserDefinedResult
UserDefinedResult -> UserDefinedResult -> Bool
UserDefinedResult -> UserDefinedResult -> Ordering
UserDefinedResult -> UserDefinedResult -> UserDefinedResult
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: UserDefinedResult -> UserDefinedResult -> UserDefinedResult
$cmin :: UserDefinedResult -> UserDefinedResult -> UserDefinedResult
max :: UserDefinedResult -> UserDefinedResult -> UserDefinedResult
$cmax :: UserDefinedResult -> UserDefinedResult -> UserDefinedResult
>= :: UserDefinedResult -> UserDefinedResult -> Bool
$c>= :: UserDefinedResult -> UserDefinedResult -> Bool
> :: UserDefinedResult -> UserDefinedResult -> Bool
$c> :: UserDefinedResult -> UserDefinedResult -> Bool
<= :: UserDefinedResult -> UserDefinedResult -> Bool
$c<= :: UserDefinedResult -> UserDefinedResult -> Bool
< :: UserDefinedResult -> UserDefinedResult -> Bool
$c< :: UserDefinedResult -> UserDefinedResult -> Bool
compare :: UserDefinedResult -> UserDefinedResult -> Ordering
$ccompare :: UserDefinedResult -> UserDefinedResult -> Ordering
Ord, Int -> UserDefinedResult -> ShowS
[UserDefinedResult] -> ShowS
UserDefinedResult -> ResultLocale
forall a.
(Int -> a -> ShowS)
-> (a -> ResultLocale) -> ([a] -> ShowS) -> Show a
showList :: [UserDefinedResult] -> ShowS
$cshowList :: [UserDefinedResult] -> ShowS
show :: UserDefinedResult -> ResultLocale
$cshow :: UserDefinedResult -> ResultLocale
showsPrec :: Int -> UserDefinedResult -> ShowS
$cshowsPrec :: Int -> UserDefinedResult -> ShowS
Show)

-- | This is a localisation of the specified simulation result.
data LocalisedResult =
  LocalisedResult { LocalisedResult -> Map ResultLocale ResultLocale
localisedResultDescriptions :: M.Map ResultLocale ResultDescription,
                    -- ^ The localised descriptions.
                    LocalisedResult -> Map ResultLocale ResultLocale
localisedResultTitles :: M.Map ResultLocale ResultDescription
                    -- ^ The localised titles.
                  } deriving (LocalisedResult -> LocalisedResult -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LocalisedResult -> LocalisedResult -> Bool
$c/= :: LocalisedResult -> LocalisedResult -> Bool
== :: LocalisedResult -> LocalisedResult -> Bool
$c== :: LocalisedResult -> LocalisedResult -> Bool
Eq, Eq LocalisedResult
LocalisedResult -> LocalisedResult -> Bool
LocalisedResult -> LocalisedResult -> Ordering
LocalisedResult -> LocalisedResult -> LocalisedResult
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: LocalisedResult -> LocalisedResult -> LocalisedResult
$cmin :: LocalisedResult -> LocalisedResult -> LocalisedResult
max :: LocalisedResult -> LocalisedResult -> LocalisedResult
$cmax :: LocalisedResult -> LocalisedResult -> LocalisedResult
>= :: LocalisedResult -> LocalisedResult -> Bool
$c>= :: LocalisedResult -> LocalisedResult -> Bool
> :: LocalisedResult -> LocalisedResult -> Bool
$c> :: LocalisedResult -> LocalisedResult -> Bool
<= :: LocalisedResult -> LocalisedResult -> Bool
$c<= :: LocalisedResult -> LocalisedResult -> Bool
< :: LocalisedResult -> LocalisedResult -> Bool
$c< :: LocalisedResult -> LocalisedResult -> Bool
compare :: LocalisedResult -> LocalisedResult -> Ordering
$ccompare :: LocalisedResult -> LocalisedResult -> Ordering
Ord, Int -> LocalisedResult -> ShowS
[LocalisedResult] -> ShowS
LocalisedResult -> ResultLocale
forall a.
(Int -> a -> ShowS)
-> (a -> ResultLocale) -> ([a] -> ShowS) -> Show a
showList :: [LocalisedResult] -> ShowS
$cshowList :: [LocalisedResult] -> ShowS
show :: LocalisedResult -> ResultLocale
$cshow :: LocalisedResult -> ResultLocale
showsPrec :: Int -> LocalisedResult -> ShowS
$cshowsPrec :: Int -> LocalisedResult -> ShowS
Show)

-- | A name used for indentifying the results when generating output.
type ResultName = String

-- | A description used for describing the results when generating output.
type ResultDescription = String

-- | The result entity identifier.
data ResultId = TimeId
                -- ^ A 'time' computation.
              | VectorId
                -- ^ Describes a vector.
              | VectorItemId String
                -- ^ Describes a vector item with the specified subscript.
              | SamplingStatsId
                -- ^ A 'SamplingStats' value.
              | SamplingStatsCountId
                -- ^ Property 'samplingStatsCount'.
              | SamplingStatsMinId
                -- ^ Property 'samplingStatsMin'.
              | SamplingStatsMaxId
                -- ^ Property 'samplingStatsMax'.
              | SamplingStatsMeanId
                -- ^ Property 'samplingStatsMean'.
              | SamplingStatsMean2Id
                -- ^ Property 'samplingStatsMean2'.
              | SamplingStatsVarianceId
                -- ^ Property 'samplingStatsVariance'.
              | SamplingStatsDeviationId
                -- ^ Property 'samplingStatsDeviation'.
              | SamplingCounterId
                -- ^ A 'SamplingCounter' value.
              | SamplingCounterValueId
                -- ^ Property 'samplingCounterValue'.
              | SamplingCounterStatsId
                -- ^ Property 'samplingCounterStats'.
              | TimingStatsId
                -- ^ A 'TimingStats' value.
              | TimingStatsCountId
                -- ^ Property 'timingStatsCount'.
              | TimingStatsMinId
                -- ^ Property 'timingStatsMin'.
              | TimingStatsMaxId
                -- ^ Property 'timingStatsMax'.
              | TimingStatsMeanId
                -- ^ Property 'timingStatsMean'.
              | TimingStatsVarianceId
                -- ^ Property 'timingStatsVariance'.
              | TimingStatsDeviationId
                -- ^ Property 'timingStatsDeviation'.
              | TimingStatsMinTimeId
                -- ^ Property 'timingStatsMinTime'.
              | TimingStatsMaxTimeId
                -- ^ Property 'timingStatsMaxTime'.
              | TimingStatsStartTimeId
                -- ^ Property 'timingStatsStartTime'.
              | TimingStatsLastTimeId
                -- ^ Property 'timingStatsLastTime'.
              | TimingStatsSumId
                -- ^ Property 'timingStatsSum'.
              | TimingStatsSum2Id
                -- ^ Property 'timingStatsSum2'.
              | TimingCounterId
                -- ^ A 'TimingCounter' value.
              | TimingCounterValueId
                -- ^ Property 'timingCounterValue'.
              | TimingCounterStatsId
                -- ^ Property 'timingCounterStats'.
              | FiniteQueueId
                -- ^ A finite 'Q.Queue'.
              | InfiniteQueueId
                -- ^ An infinite 'IQ.Queue'.
              | EnqueueStrategyId
                -- ^ Property 'Q.enqueueStrategy'.
              | EnqueueStoringStrategyId
                -- ^ Property 'Q.enqueueStoringStrategy'.
              | DequeueStrategyId
                -- ^ Property 'Q.dequeueStrategy'.
              | QueueNullId
                -- ^ Property 'Q.queueNull'.
              | QueueFullId
                -- ^ Property 'Q.queueFull'.
              | QueueMaxCountId
                -- ^ Property 'Q.queueMaxCount'.
              | QueueCountId
                -- ^ Property 'Q.queueCount'.
              | QueueCountStatsId
                -- ^ Property 'Q.queueCountStats'.
              | EnqueueCountId
                -- ^ Property 'Q.enqueueCount'.
              | EnqueueLostCountId
                -- ^ Property 'Q.enqueueLostCount'.
              | EnqueueStoreCountId
                -- ^ Property 'Q.enqueueStoreCount'.
              | DequeueCountId
                -- ^ Property 'Q.dequeueCount'.
              | DequeueExtractCountId
                -- ^ Property 'Q.dequeueExtractCount'.
              | QueueLoadFactorId
                -- ^ Property 'Q.queueLoadFactor'.
              | EnqueueRateId
                -- ^ Property 'Q.enqueueRate'.
              | EnqueueStoreRateId
                -- ^ Property 'Q.enqueueStoreRate'.
              | DequeueRateId
                -- ^ Property 'Q.dequeueRate'.
              | DequeueExtractRateId
                -- ^ Property 'Q.dequeueExtractRate'.
              | QueueWaitTimeId
                -- ^ Property 'Q.queueWaitTime'.
              | QueueTotalWaitTimeId
                -- ^ Property 'Q.queueTotalWaitTime'.
              | EnqueueWaitTimeId
                -- ^ Property 'Q.enqueueWaitTime'.
              | DequeueWaitTimeId
                -- ^ Property 'Q.dequeueWaitTime'.
              | QueueRateId
                -- ^ Property 'Q.queueRate'.
              | ArrivalTimerId
                -- ^ An 'ArrivalTimer'.
              | ArrivalProcessingTimeId
                -- ^ Property 'arrivalProcessingTime'.
              | ServerId
                -- ^ Represents a 'Server'.
              | ServerInitStateId
                -- ^ Property 'serverInitState'.
              | ServerStateId
                -- ^ Property 'serverState'.
              | ServerTotalInputWaitTimeId
                -- ^ Property 'serverTotalInputWaitTime'.
              | ServerTotalProcessingTimeId
                -- ^ Property 'serverTotalProcessingTime'.
              | ServerTotalOutputWaitTimeId
                -- ^ Property 'serverTotalOutputWaitTime'.
              | ServerTotalPreemptionTimeId
                -- ^ Property 'serverTotalPreemptionTime'.
              | ServerInputWaitTimeId
                -- ^ Property 'serverInputWaitTime'.
              | ServerProcessingTimeId
                -- ^ Property 'serverProcessingTime'.
              | ServerOutputWaitTimeId
                -- ^ Property 'serverOutputWaitTime'.
              | ServerPreemptionTimeId
                -- ^ Property 'serverPreemptionTime'.
              | ServerInputWaitFactorId
                -- ^ Property 'serverInputWaitFactor'.
              | ServerProcessingFactorId
                -- ^ Property 'serverProcessingFactor'.
              | ServerOutputWaitFactorId
                -- ^ Property 'serverOutputWaitFactor'.
              | ServerPreemptionFactorId
                -- ^ Property 'serverPreemptionFactor'.
              | ActivityId
                -- ^ Represents an 'Activity'.
              | ActivityInitStateId
                -- ^ Property 'activityInitState'.
              | ActivityStateId
                -- ^ Property 'activityState'.
              | ActivityTotalUtilisationTimeId
                -- ^ Property 'activityTotalUtilisationTime'.
              | ActivityTotalIdleTimeId
                -- ^ Property 'activityTotalIdleTime'.
              | ActivityTotalPreemptionTimeId
                -- ^ Property 'activityTotalPreemptionTime'.
              | ActivityUtilisationTimeId
                -- ^ Property 'activityUtilisationTime'.
              | ActivityIdleTimeId
                -- ^ Property 'activityIdleTime'.
              | ActivityPreemptionTimeId
                -- ^ Property 'activityPreemptionTime'.
              | ActivityUtilisationFactorId
                -- ^ Property 'activityUtilisationFactor'.
              | ActivityIdleFactorId
                -- ^ Property 'activityIdleFactor'.
              | ActivityPreemptionFactorId
                -- ^ Property 'activityPreemptionFactor'.
              | ResourceId
                -- ^ Represents a 'Resource'.
              | ResourceCountId
                -- ^ Property 'resourceCount'.
              | ResourceCountStatsId
                -- ^ Property 'resourceCountStats'.
              | ResourceUtilisationCountId
                -- ^ Property 'resourceUtilisationCount'.
              | ResourceUtilisationCountStatsId
                -- ^ Property 'resourceUtilisationCountStats'.
              | ResourceQueueCountId
                -- ^ Property 'resourceQueueCount'.
              | ResourceQueueCountStatsId
                -- ^ Property 'resourceQueueCountStats'.
              | ResourceTotalWaitTimeId
                -- ^ Property 'resourceTotalWaitTime'.
              | ResourceWaitTimeId
                -- ^ Property 'resourceWaitTime'.
              | OperationId
                -- ^ Represents an 'Operation'.
              | OperationTotalUtilisationTimeId
                -- ^ Property 'operationTotalUtilisationTime'.
              | OperationTotalPreemptionTimeId
                -- ^ Property 'operationTotalPreemptionTime'.
              | OperationUtilisationTimeId
                -- ^ Property 'operationUtilisationTime'.
              | OperationPreemptionTimeId
                -- ^ Property 'operationPreemptionTime'.
              | OperationUtilisationFactorId
                -- ^ Property 'operationUtilisationFactor'.
              | OperationPreemptionFactorId
                -- ^ Property 'operationPreemptionFactor'.
              | UserDefinedResultId UserDefinedResult
                -- ^ An user defined description.
              | LocalisedResultId LocalisedResult
                -- ^ A localised property or object name.
              deriving (ResultId -> ResultId -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResultId -> ResultId -> Bool
$c/= :: ResultId -> ResultId -> Bool
== :: ResultId -> ResultId -> Bool
$c== :: ResultId -> ResultId -> Bool
Eq, Eq ResultId
ResultId -> ResultId -> Bool
ResultId -> ResultId -> Ordering
ResultId -> ResultId -> ResultId
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ResultId -> ResultId -> ResultId
$cmin :: ResultId -> ResultId -> ResultId
max :: ResultId -> ResultId -> ResultId
$cmax :: ResultId -> ResultId -> ResultId
>= :: ResultId -> ResultId -> Bool
$c>= :: ResultId -> ResultId -> Bool
> :: ResultId -> ResultId -> Bool
$c> :: ResultId -> ResultId -> Bool
<= :: ResultId -> ResultId -> Bool
$c<= :: ResultId -> ResultId -> Bool
< :: ResultId -> ResultId -> Bool
$c< :: ResultId -> ResultId -> Bool
compare :: ResultId -> ResultId -> Ordering
$ccompare :: ResultId -> ResultId -> Ordering
Ord, Int -> ResultId -> ShowS
[ResultId] -> ShowS
ResultId -> ResultLocale
forall a.
(Int -> a -> ShowS)
-> (a -> ResultLocale) -> ([a] -> ShowS) -> Show a
showList :: [ResultId] -> ShowS
$cshowList :: [ResultId] -> ShowS
show :: ResultId -> ResultLocale
$cshow :: ResultId -> ResultLocale
showsPrec :: Int -> ResultId -> ShowS
$cshowsPrec :: Int -> ResultId -> ShowS
Show)

-- | The Russian locale.
russianResultLocale :: ResultLocale
russianResultLocale :: ResultLocale
russianResultLocale = ResultLocale
"ru"

-- | The English locale.
englishResultLocale :: ResultLocale
englishResultLocale :: ResultLocale
englishResultLocale = ResultLocale
"en"

-- | Lookup a localisation by the specified locale.
lookupResultLocalisation :: ResultLocale -> M.Map ResultLocale ResultDescription -> ResultDescription
lookupResultLocalisation :: ResultLocale -> Map ResultLocale ResultLocale -> ResultLocale
lookupResultLocalisation ResultLocale
loc Map ResultLocale ResultLocale
m =
  case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup ResultLocale
loc Map ResultLocale ResultLocale
m of
    Just ResultLocale
x  -> ResultLocale
x
    Maybe ResultLocale
Nothing ->
      case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup ResultLocale
russianResultLocale Map ResultLocale ResultLocale
m of
        Just ResultLocale
x  -> ResultLocale
x
        Maybe ResultLocale
Nothing ->
          case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup ResultLocale
englishResultLocale Map ResultLocale ResultLocale
m of
            Just ResultLocale
x  -> ResultLocale
x
            Maybe ResultLocale
Nothing -> ResultLocale
""

-- | Return the path result localisation.
pathResultLocalisation :: (ResultId -> ResultDescription) -> [ResultId] -> ResultDescription
pathResultLocalisation :: (ResultId -> ResultLocale) -> [ResultId] -> ResultLocale
pathResultLocalisation ResultId -> ResultLocale
loc [ResultId]
is = [ResultId] -> [ShowS] -> ResultLocale
loop [ResultId]
is []
  where loop :: [ResultId] -> [ShowS] -> ResultLocale
loop [] [ShowS]
acc                      = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall a b. (a -> b) -> a -> b
($) [] (forall a. [a] -> [a]
reverse [ShowS]
acc)
        loop (ResultId
x : [ResultId]
xs) []                 = [ResultId] -> [ShowS] -> ResultLocale
loop [ResultId]
xs [(ResultId -> ResultLocale
loc ResultId
x forall a. [a] -> [a] -> [a]
++)]
        loop ((VectorItemId ResultLocale
s) : [ResultId]
xs) [ShowS]
acc = [ResultId] -> [ShowS] -> ResultLocale
loop [ResultId]
xs forall a b. (a -> b) -> a -> b
$ (ResultLocale
s forall a. [a] -> [a] -> [a]
++) forall a. a -> [a] -> [a]
: (ResultLocale
" " forall a. [a] -> [a] -> [a]
++) forall a. a -> [a] -> [a]
: [ShowS]
acc
        loop (ResultId
x : [ResultId]
xs) [ShowS]
acc                = [ResultId] -> [ShowS] -> ResultLocale
loop [ResultId]
xs forall a b. (a -> b) -> a -> b
$ (ResultId -> ResultLocale
loc ResultId
x forall a. [a] -> [a] -> [a]
++) forall a. a -> [a] -> [a]
: (ResultLocale
" / " forall a. [a] -> [a] -> [a]
++) forall a. a -> [a] -> [a]
: [ShowS]
acc

-- | Localise the path result description.
localisePathResultDescription :: ResultLocalisation -> [ResultId] -> ResultDescription
localisePathResultDescription :: ResultLocalisation -> [ResultId] -> ResultLocale
localisePathResultDescription ResultLocalisation
loc [ResultId]
is = (ResultId -> ResultLocale) -> [ResultId] -> ResultLocale
pathResultLocalisation (ResultLocalisation -> ResultId -> ResultLocale
localiseResultDescription ResultLocalisation
loc) [ResultId]
is

-- | Localise the path result title.
localisePathResultTitle :: ResultLocalisation -> [ResultId] -> ResultDescription
localisePathResultTitle :: ResultLocalisation -> [ResultId] -> ResultLocale
localisePathResultTitle ResultLocalisation
loc [ResultId]
is = (ResultId -> ResultLocale) -> [ResultId] -> ResultLocale
pathResultLocalisation (ResultLocalisation -> ResultId -> ResultLocale
localiseResultTitle ResultLocalisation
loc) [ResultId]
is

-- | Convert the result name to title.
resultNameToTitle :: ResultName -> ResultDescription
resultNameToTitle :: ShowS
resultNameToTitle =
  [ResultLocale] -> ResultLocale
unwords forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall a b. (a -> b) -> [a] -> [b]
map (forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (\Char
x Char
y -> Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ Char -> Bool
isUpper Char
y)) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  ResultLocale -> [ResultLocale]
words