{-# OPTIONS_HADDOCK show-extensions #-}
{-# LANGUAGE NoImplicitPrelude #-}

-- |
-- Module      :  CLI.Arguments
-- Copyright   :  (c) OleksandrZhabenko 2021-2023
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  oleksandr.zhabenko@yahoo.com
--
-- A library to process command line arguments in some more convenient way.

module CLI.Arguments where

import Data.Monoid (mappend)
import GHC.Base
import Text.Show
import GHC.List

-- | Data to encode the possible cli-arguments of some logics below. The arguments are separated
-- by the spaces characters one from another.
data Arguments =
  A String -- ^ If for encoding of the argument just one 'String' is used without spaces.
  | B GQtyArgs Delimiter [String] -- ^ If there is a certain quantity of consequent arguments that indicates the one semantical value.
  | C Delimiter [String] -- ^ If the quantity of the consequent arguments that forms a semantic value is not known, but they are enclosed by the delimiter or its modification.
      deriving Arguments -> Arguments -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Arguments -> Arguments -> Bool
$c/= :: Arguments -> Arguments -> Bool
== :: Arguments -> Arguments -> Bool
$c== :: Arguments -> Arguments -> Bool
Eq

type Args = [Arguments]

type Specification = (Delimiter,GQtyArgs)

type CLSpecifications = [Specification]

type Delimiter = String

type GQtyArgs = Int

type FirstCharacter = Char

type FirstChars = (Char,Char)

instance Show Arguments where
  show :: Arguments -> String
show (A String
xs) = String
xs
  show (B GQtyArgs
n String
ys [String]
yss) = Char
' 'forall a. a -> [a] -> [a]
:String
ys forall a. Monoid a => a -> a -> a
`mappend` forall a b. (a -> [b]) -> [a] -> [b]
concatMap (\String
xs ->Char
' 'forall a. a -> [a] -> [a]
:forall a. Show a => a -> String
show String
xs) (forall a. GQtyArgs -> [a] -> [a]
take GQtyArgs
n [String]
yss)
  show (C String
xs [String]
xss) = Char
' 'forall a. a -> [a] -> [a]
:String
xs forall a. Monoid a => a -> a -> a
`mappend` forall a b. (a -> [b]) -> [a] -> [b]
concatMap (\String
ys ->Char
' 'forall a. a -> [a] -> [a]
:forall a. Show a => a -> String
show String
ys) [String]
xss forall a. Monoid a => a -> a -> a
`mappend` (Char
' 'forall a. a -> [a] -> [a]
:String
xs)

isA :: Arguments -> Bool
isA :: Arguments -> Bool
isA (A String
_) = Bool
True
isA Arguments
_ = Bool
False

isB :: Arguments -> Bool
isB :: Arguments -> Bool
isB (B GQtyArgs
_ String
_ [String]
_) = Bool
True
isB Arguments
_ = Bool
False

isC :: Arguments -> Bool
isC :: Arguments -> Bool
isC (C String
_ [String]
_) = Bool
True
isC Arguments
_ = Bool
False

nullArguments :: Arguments -> Bool
nullArguments :: Arguments -> Bool
nullArguments (A String
xs) = forall a. [a] -> Bool
null String
xs
nullArguments (B GQtyArgs
n String
ys [String]
yss) = GQtyArgs
n forall a. Eq a => a -> a -> Bool
/= forall a. [a] -> GQtyArgs
length [String]
yss Bool -> Bool -> Bool
|| forall a. [a] -> Bool
null String
ys  Bool -> Bool -> Bool
|| forall a. [a] -> Bool
null [String]
yss
nullArguments (C String
xs [String]
xss) = forall a. [a] -> Bool
null String
xs Bool -> Bool -> Bool
|| forall a. [a] -> Bool
null [String]
xss

notNullArguments :: Arguments -> Bool
notNullArguments :: Arguments -> Bool
notNullArguments (A (Char
_:String
_)) =  Bool
True
notNullArguments (A String
_) = Bool
False
notNullArguments (B GQtyArgs
n (Char
_:String
_) yss :: [String]
yss@(String
_:[String]
_)) = GQtyArgs
n forall a. Eq a => a -> a -> Bool
== forall a. [a] -> GQtyArgs
length [String]
yss
notNullArguments (B GQtyArgs
_ String
_ [String]
_) = Bool
False
notNullArguments (C (Char
_:String
_) (String
_:[String]
_)) = Bool
True
notNullArguments Arguments
_ = Bool
False

b1Args2AArgs :: Arguments -> Arguments
b1Args2AArgs :: Arguments -> Arguments
b1Args2AArgs b :: Arguments
b@(B GQtyArgs
n String
_ [String
ys])
 | GQtyArgs
n forall a. Ord a => a -> a -> Bool
< GQtyArgs
1 = String -> Arguments
A String
ys
 | Bool
otherwise = Arguments
b
b1Args2AArgs Arguments
x = Arguments
x