    {-# LANGUAGE CPP #-}
    module GetOpt.Declarative.Util (mkUsageInfo) where

    import           Prelude ()
    import           Test.Hspec.Core.Compat

    import           System.Console.GetOpt

    import           Test.Hspec.Core.Util

    modifyHelp :: (String -> String) -> OptDescr a -> OptDescr a
    modifyHelp :: forall a. (String -> String) -> OptDescr a -> OptDescr a
    modifyHelp String -> String
    modify (Option String
    s [String]
    n ArgDescr a
    a String
    help) = String -> [String] -> ArgDescr a -> String -> OptDescr a
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option String
    s [String]
    n ArgDescr a
    a (String -> String
    modify String
    help)

    mkUsageInfo :: String -> [OptDescr a] -> String
    mkUsageInfo :: forall a. String -> [OptDescr a] -> String
    mkUsageInfo String
    title = String -> [OptDescr a] -> String
    forall a. String -> [OptDescr a] -> String
    usageInfo String
    title ([OptDescr a] -> String)
    -> ([OptDescr a] -> [OptDescr a]) -> [OptDescr a] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [OptDescr a] -> [OptDescr a]
    forall a. [OptDescr a] -> [OptDescr a]
    addLineBreaksForHelp ([OptDescr a] -> [OptDescr a])
    -> ([OptDescr a] -> [OptDescr a]) -> [OptDescr a] -> [OptDescr a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [OptDescr a] -> [OptDescr a]
    forall a. [OptDescr a] -> [OptDescr a]
    condenseNoOptions

    addLineBreaksForHelp :: [OptDescr a] -> [OptDescr a]
    addLineBreaksForHelp :: forall a. [OptDescr a] -> [OptDescr a]
    addLineBreaksForHelp [OptDescr a]
    options = (OptDescr a -> OptDescr a) -> [OptDescr a] -> [OptDescr a]
    forall a b. (a -> b) -> [a] -> [b]
    map ((String -> String) -> OptDescr a -> OptDescr a
    forall a. (String -> String) -> OptDescr a -> OptDescr a
    modifyHelp String -> String
    addLineBreaks) [OptDescr a]
    options
      where
        withoutHelpWidth :: [OptDescr a] -> Int
    withoutHelpWidth = String -> Int
    maxLength (String -> Int) -> ([OptDescr a] -> String) -> [OptDescr a] -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [OptDescr a] -> String
    forall a. String -> [OptDescr a] -> String
    usageInfo String
    "" ([OptDescr a] -> String)
    -> ([OptDescr a] -> [OptDescr a]) -> [OptDescr a] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (OptDescr a -> OptDescr a) -> [OptDescr a] -> [OptDescr a]
    forall a b. (a -> b) -> [a] -> [b]
    map OptDescr a -> OptDescr a
    forall {a}. OptDescr a -> OptDescr a
    removeHelp
        helpWidth :: Int
    helpWidth = Int
    80 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - [OptDescr a] -> Int
    forall {a}. [OptDescr a] -> Int
    withoutHelpWidth [OptDescr a]
    options

        addLineBreaks :: String -> String
    addLineBreaks = [String] -> String
    unlines ([String] -> String) -> (String -> [String]) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String -> [String]
    lineBreaksAt Int
    helpWidth

        maxLength :: String -> Int
    maxLength = [Int] -> Int
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum ([Int] -> Int) -> (String -> [Int]) -> String -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String -> Int) -> [String] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length ([String] -> [Int]) -> (String -> [String]) -> String -> [Int]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String]
    lines
        removeHelp :: OptDescr a -> OptDescr a
    removeHelp = (String -> String) -> OptDescr a -> OptDescr a
    forall a. (String -> String) -> OptDescr a -> OptDescr a
    modifyHelp (String -> String -> String
    forall a b. a -> b -> a
    const String
    "")

    condenseNoOptions :: [OptDescr a] -> [OptDescr a]
    condenseNoOptions :: forall a. [OptDescr a] -> [OptDescr a]
    condenseNoOptions [OptDescr a]
    options = case [OptDescr a]
    options of
      Option String
    short [String
    optionA] ArgDescr a
    arg String
    help : Option String
    "" [String
    optionB] ArgDescr a
    _ String
    _ : [OptDescr a]
    ys | String
    optionB String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == (String
    "no-" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    optionA) ->
        String -> [String] -> ArgDescr a -> String -> OptDescr a
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option String
    short [String
    "[no-]" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    optionA] ArgDescr a
    arg String
    help OptDescr a -> [OptDescr a] -> [OptDescr a]
    forall a. a -> [a] -> [a]
    : [OptDescr a] -> [OptDescr a]
    forall a. [OptDescr a] -> [OptDescr a]
    condenseNoOptions [OptDescr a]
    ys
      OptDescr a
    x : [OptDescr a]
    xs -> OptDescr a
    x OptDescr a -> [OptDescr a] -> [OptDescr a]
    forall a. a -> [a] -> [a]
    : [OptDescr a] -> [OptDescr a]
    forall a. [OptDescr a] -> [OptDescr a]
    condenseNoOptions [OptDescr a]
    xs
      [] -> []