{-# LANGUAGE OverloadedStrings #-}

module OptEnvConf.Output where

import Data.List (intercalate, intersperse)
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
import Data.Maybe
import Data.Text (Text)
import qualified Data.Text as T
import Data.Version
import GHC.Stack (SrcLoc, prettySrcLoc)
import OptEnvConf.Args (Dashed (..))
import qualified OptEnvConf.Args as Args
import OptEnvConf.Parser
import Text.Colour

stringLines :: String -> [[Chunk]]
stringLines :: String -> [[Chunk]]
stringLines String
s =
  let ls :: [Text]
ls = Text -> [Text]
T.lines (String -> Text
T.pack String
s)
   in (Text -> [Chunk]) -> [Text] -> [[Chunk]]
forall a b. (a -> b) -> [a] -> [b]
map (Chunk -> [Chunk]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Chunk -> [Chunk]) -> (Text -> Chunk) -> Text -> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk) [Text]
ls

progNameChunk :: String -> Chunk
progNameChunk :: String -> Chunk
progNameChunk = Colour -> Chunk -> Chunk
fore Colour
yellow (Chunk -> Chunk) -> (String -> Chunk) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk (Text -> Chunk) -> (String -> Text) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

versionChunk :: Version -> Chunk
versionChunk :: Version -> Chunk
versionChunk = Text -> Chunk
chunk (Text -> Chunk) -> (Version -> Text) -> Version -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (Version -> String) -> Version -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Version -> String
showVersion

usageChunk :: Chunk
usageChunk :: Chunk
usageChunk = Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
"Usage: "

commandChunk :: String -> Chunk
commandChunk :: String -> Chunk
commandChunk = Colour -> Chunk -> Chunk
fore Colour
magenta (Chunk -> Chunk) -> (String -> Chunk) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk (Text -> Chunk) -> (String -> Text) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

functionChunk :: Text -> Chunk
functionChunk :: Text -> Chunk
functionChunk = Colour -> Chunk -> Chunk
fore Colour
yellow (Chunk -> Chunk) -> (Text -> Chunk) -> Text -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk

mMetavarChunk :: Maybe Metavar -> Chunk
mMetavarChunk :: Maybe String -> Chunk
mMetavarChunk = String -> Chunk
metavarChunk (String -> Chunk)
-> (Maybe String -> String) -> Maybe String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
"METAVAR"

metavarChunk :: Metavar -> Chunk
metavarChunk :: String -> Chunk
metavarChunk = Colour -> Chunk -> Chunk
fore Colour
yellow (Chunk -> Chunk) -> (String -> Chunk) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk (Text -> Chunk) -> (String -> Text) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

dashedChunks :: [Dashed] -> Maybe [Chunk]
dashedChunks :: [Dashed] -> Maybe [Chunk]
dashedChunks = (NonEmpty Dashed -> [Chunk])
-> Maybe (NonEmpty Dashed) -> Maybe [Chunk]
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmpty Dashed -> [Chunk]
dashedChunksNE (Maybe (NonEmpty Dashed) -> Maybe [Chunk])
-> ([Dashed] -> Maybe (NonEmpty Dashed))
-> [Dashed]
-> Maybe [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Dashed] -> Maybe (NonEmpty Dashed)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty

dashedChunksNE :: NonEmpty Dashed -> [Chunk]
dashedChunksNE :: NonEmpty Dashed -> [Chunk]
dashedChunksNE = Chunk -> [Chunk] -> [Chunk]
forall a. a -> [a] -> [a]
intersperse (Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
"|") ([Chunk] -> [Chunk])
-> (NonEmpty Dashed -> [Chunk]) -> NonEmpty Dashed -> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Dashed -> Chunk) -> [Dashed] -> [Chunk]
forall a b. (a -> b) -> [a] -> [b]
map Dashed -> Chunk
dashedChunk ([Dashed] -> [Chunk])
-> (NonEmpty Dashed -> [Dashed]) -> NonEmpty Dashed -> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty Dashed -> [Dashed]
forall a. NonEmpty a -> [a]
NE.toList

dashedChunk :: Dashed -> Chunk
dashedChunk :: Dashed -> Chunk
dashedChunk = Colour -> Chunk -> Chunk
fore Colour
white (Chunk -> Chunk) -> (Dashed -> Chunk) -> Dashed -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk (Text -> Chunk) -> (Dashed -> Text) -> Dashed -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (Dashed -> String) -> Dashed -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dashed -> String
Args.renderDashed

envVarChunksNE :: NonEmpty String -> [Chunk]
envVarChunksNE :: NonEmpty String -> [Chunk]
envVarChunksNE = Chunk -> [Chunk] -> [Chunk]
forall a. a -> [a] -> [a]
intersperse (Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
"|") ([Chunk] -> [Chunk])
-> (NonEmpty String -> [Chunk]) -> NonEmpty String -> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Chunk) -> [String] -> [Chunk]
forall a b. (a -> b) -> [a] -> [b]
map String -> Chunk
envVarChunk ([String] -> [Chunk])
-> (NonEmpty String -> [String]) -> NonEmpty String -> [Chunk]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty String -> [String]
forall a. NonEmpty a -> [a]
NE.toList

envVarChunk :: String -> Chunk
envVarChunk :: String -> Chunk
envVarChunk = Colour -> Chunk -> Chunk
fore Colour
white (Chunk -> Chunk) -> (String -> Chunk) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk (Text -> Chunk) -> (String -> Text) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

confValChunk :: NonEmpty String -> Chunk
confValChunk :: NonEmpty String -> Chunk
confValChunk = Colour -> Chunk -> Chunk
fore Colour
white (Chunk -> Chunk)
-> (NonEmpty String -> Chunk) -> NonEmpty String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk (Text -> Chunk)
-> (NonEmpty String -> Text) -> NonEmpty String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text)
-> (NonEmpty String -> String) -> NonEmpty String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"." ([String] -> String)
-> (NonEmpty String -> [String]) -> NonEmpty String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty String -> [String]
forall a. NonEmpty a -> [a]
NE.toList

defaultValueChunks :: String -> [Chunk]
defaultValueChunks :: String -> [Chunk]
defaultValueChunks String
val = [Chunk
"default: ", Colour -> Chunk -> Chunk
fore Colour
yellow (Chunk -> Chunk) -> Chunk -> Chunk
forall a b. (a -> b) -> a -> b
$ Text -> Chunk
chunk (Text -> Chunk) -> Text -> Chunk
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
val]

exampleValuesChunks :: [String] -> [Chunk]
exampleValuesChunks :: [String] -> [Chunk]
exampleValuesChunks [String]
vals = case [String]
vals of
  [] -> []
  [String
val] -> [Chunk
"example: ", Colour -> Chunk -> Chunk
fore Colour
yellow (Chunk -> Chunk) -> Chunk -> Chunk
forall a b. (a -> b) -> a -> b
$ Text -> Chunk
chunk (Text -> Chunk) -> Text -> Chunk
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
val]
  [String]
_ -> [Chunk
"examples: ", Colour -> Chunk -> Chunk
fore Colour
yellow (Chunk -> Chunk) -> Chunk -> Chunk
forall a b. (a -> b) -> a -> b
$ Text -> Chunk
chunk (Text -> Chunk) -> Text -> Chunk
forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
T.intercalate Text
", " ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (String -> Text) -> [String] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Text
T.pack (String -> Text) -> (String -> String) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. Show a => a -> String
show) [String]
vals]

mHelpChunk :: Maybe Help -> Chunk
mHelpChunk :: Maybe String -> Chunk
mHelpChunk = Chunk -> (String -> Chunk) -> Maybe String -> Chunk
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Colour -> Chunk -> Chunk
fore Colour
red Chunk
"undocumented") String -> Chunk
helpChunk

helpChunk :: Help -> Chunk
helpChunk :: String -> Chunk
helpChunk = Colour -> Chunk -> Chunk
fore Colour
blue (Chunk -> Chunk) -> (String -> Chunk) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk (Text -> Chunk) -> (String -> Text) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

headerChunks :: Text -> [Chunk]
headerChunks :: Text -> [Chunk]
headerChunks Text
t = [Colour -> Chunk -> Chunk
fore Colour
cyan (Text -> Chunk
chunk Text
t), Chunk
":"]

syntaxChunk :: String -> Chunk
syntaxChunk :: String -> Chunk
syntaxChunk = Colour -> Chunk -> Chunk
fore Colour
blue (Chunk -> Chunk) -> (String -> Chunk) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk (Text -> Chunk) -> (String -> Text) -> String -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

mSrcLocChunk :: Maybe SrcLoc -> Chunk
mSrcLocChunk :: Maybe SrcLoc -> Chunk
mSrcLocChunk = Chunk -> (SrcLoc -> Chunk) -> Maybe SrcLoc -> Chunk
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Chunk
"without srcLoc" SrcLoc -> Chunk
srcLocChunk

srcLocChunk :: SrcLoc -> Chunk
srcLocChunk :: SrcLoc -> Chunk
srcLocChunk = Colour -> Chunk -> Chunk
fore Colour
cyan (Chunk -> Chunk) -> (SrcLoc -> Chunk) -> SrcLoc -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Chunk
chunk (Text -> Chunk) -> (SrcLoc -> Text) -> SrcLoc -> Chunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (SrcLoc -> String) -> SrcLoc -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcLoc -> String
prettySrcLoc

indent :: [[Chunk]] -> [[Chunk]]
indent :: [[Chunk]] -> [[Chunk]]
indent = ([Chunk] -> [Chunk]) -> [[Chunk]] -> [[Chunk]]
forall a b. (a -> b) -> [a] -> [b]
map (Chunk
"  " Chunk -> [Chunk] -> [Chunk]
forall a. a -> [a] -> [a]
:)

parenthesise :: [Chunk] -> [Chunk]
parenthesise :: [Chunk] -> [Chunk]
parenthesise [Chunk
c] = [Chunk
c]
parenthesise [Chunk]
cs = Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
"(" Chunk -> [Chunk] -> [Chunk]
forall a. a -> [a] -> [a]
: [Chunk]
cs [Chunk] -> [Chunk] -> [Chunk]
forall a. [a] -> [a] -> [a]
++ [Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
")"]

bracketise :: [Chunk] -> [Chunk]
bracketise :: [Chunk] -> [Chunk]
bracketise [Chunk
c] = [Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
"[", Chunk
c, Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
"]"]
bracketise [Chunk]
cs = Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
"[" Chunk -> [Chunk] -> [Chunk]
forall a. a -> [a] -> [a]
: [Chunk]
cs [Chunk] -> [Chunk] -> [Chunk]
forall a. [a] -> [a] -> [a]
++ [Colour -> Chunk -> Chunk
fore Colour
cyan Chunk
"]"]