-- |
--
-- Module      : Ronn.OptEnvConf.Env
-- Copyright   : (c) 2024 Patrick Brisbin
-- License     : AGPL-3
-- Maintainer  : pbrisbin@gmail.com
-- Stability   : experimental
-- Portability : POSIX
module Ronn.OptEnvConf.Env
  ( envDefinitions
  ) where

import Prelude

import Data.Foldable (toList)
import Data.List (intersperse)
import Data.String (IsString (..))
import OptEnvConf (Parser)
import OptEnvConf.Doc (AnyDocs (..), EnvDoc (..), parserEnvDocs)
import Ronn.AST

envDefinitions :: Parser a -> [Definition]
envDefinitions :: forall a. Parser a -> [Definition]
envDefinitions = AnyDocs EnvDoc -> [Definition]
go (AnyDocs EnvDoc -> [Definition])
-> (Parser a -> AnyDocs EnvDoc) -> Parser a -> [Definition]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser a -> AnyDocs EnvDoc
forall a. Parser a -> AnyDocs EnvDoc
parserEnvDocs
 where
  go :: AnyDocs EnvDoc -> [Definition]
  go :: AnyDocs EnvDoc -> [Definition]
go = \case
    AnyDocsCommands {} -> [] -- TODO
    AnyDocsAnd [AnyDocs EnvDoc]
ds -> (AnyDocs EnvDoc -> [Definition])
-> [AnyDocs EnvDoc] -> [Definition]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs EnvDoc -> [Definition]
go [AnyDocs EnvDoc]
ds
    AnyDocsOr [AnyDocs EnvDoc]
ds -> (AnyDocs EnvDoc -> [Definition])
-> [AnyDocs EnvDoc] -> [Definition]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnyDocs EnvDoc -> [Definition]
go [AnyDocs EnvDoc]
ds
    AnyDocsSingle EnvDoc
d -> [EnvDoc -> Definition
envDocDefinition EnvDoc
d]

envDocDefinition :: EnvDoc -> Definition
envDocDefinition :: EnvDoc -> Definition
envDocDefinition EnvDoc
doc =
  Definition
    { Part
name :: Part
$sel:name:Definition :: Part
name
    , $sel:description:Definition :: Line
description = [Part] -> Line
Line ([Part] -> Line) -> [Part] -> Line
forall a b. (a -> b) -> a -> b
$ [Part] -> (String -> [Part]) -> Maybe String -> [Part]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Part -> [Part]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Part -> [Part]) -> (String -> Part) -> String -> [Part]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Part
forall a. IsString a => String -> a
fromString) (Maybe String -> [Part]) -> Maybe String -> [Part]
forall a b. (a -> b) -> a -> b
$ EnvDoc -> Maybe String
envDocHelp EnvDoc
doc
    , $sel:content:Definition :: Maybe [Content]
content = Maybe [Content]
forall a. Maybe a
Nothing
    }
 where
  name :: Part
name =
    [Part] -> Part
Concat ([Part] -> Part) -> [Part] -> Part
forall a b. (a -> b) -> a -> b
$
      [Part] -> [Part]
addArgument ([Part] -> [Part]) -> [Part] -> [Part]
forall a b. (a -> b) -> a -> b
$
        Part -> [Part] -> [Part]
forall a. a -> [a] -> [a]
intersperse Part
"|" ([Part] -> [Part]) -> [Part] -> [Part]
forall a b. (a -> b) -> a -> b
$
          (String -> Part) -> [String] -> [Part]
forall a b. (a -> b) -> [a] -> [b]
map (Part -> Part
Code (Part -> Part) -> (String -> Part) -> String -> Part
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Part
forall a. IsString a => String -> a
fromString) ([String] -> [Part]) -> [String] -> [Part]
forall a b. (a -> b) -> a -> b
$
            NonEmpty String -> [String]
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty String -> [String]) -> NonEmpty String -> [String]
forall a b. (a -> b) -> a -> b
$
              EnvDoc -> NonEmpty String
envDocVars EnvDoc
doc

  addArgument :: [Part] -> [Part]
addArgument = case EnvDoc -> Maybe String
envDocMetavar EnvDoc
doc of
    Maybe String
Nothing -> [Part] -> [Part]
forall a. a -> a
id
    Just String
arg -> ([Part] -> [Part] -> [Part]
forall a. Semigroup a => a -> a -> a
<> [Part
"=", Part -> Part
Variable (Part -> Part) -> Part -> Part
forall a b. (a -> b) -> a -> b
$ String -> Part
forall a. IsString a => String -> a
fromString String
arg])