{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

module Configuration
  ( Configuration (..),
    parser,
  )
where

import Data.Text (Text)
import Data.Time.Calendar (Year)
import Defaults (Defaults (..), dHomePage, dName)
import Distribution.SPDX.LicenseId (LicenseId (Unlicense))
import Network.URI (URI, parseURI)
import Options.Applicative
  ( Parser,
    auto,
    help,
    hidden,
    internal,
    long,
    metavar,
    option,
    showDefault,
    strOption,
    value,
  )
import Options.Applicative.Builder (maybeReader)

data Configuration = Configuration
  { Configuration -> Text
name :: Text,
    Configuration -> URI
homepage :: URI,
    Configuration -> Text
author :: Text,
    Configuration -> Text
maintainer :: Text,
    Configuration -> LicenseId
licence :: LicenseId,
    Configuration -> FilePath
path :: FilePath,
    Configuration -> Year
year :: Year
  }

parser :: Defaults -> Parser Configuration
parser :: Defaults -> Parser Configuration
parser ds :: Defaults
ds@(Defaults {Year
FilePath
Text
URI
dOrigin :: URI
dAuthor :: Text
dMaintainer :: Text
dPath :: FilePath
dYear :: Year
dOrigin :: Defaults -> URI
dAuthor :: Defaults -> Text
dMaintainer :: Defaults -> Text
dPath :: Defaults -> FilePath
dYear :: Defaults -> Year
..}) =
  Text
-> URI
-> Text
-> Text
-> LicenseId
-> FilePath
-> Year
-> Configuration
Configuration
    (Text
 -> URI
 -> Text
 -> Text
 -> LicenseId
 -> FilePath
 -> Year
 -> Configuration)
-> Parser Text
-> Parser
     (URI
      -> Text -> Text -> LicenseId -> FilePath -> Year -> Configuration)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption
      ( FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"name"
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Name of the new project."
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"NAME"
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> Text -> Mod OptionFields Text
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (Defaults -> Text
dName Defaults
ds)
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields Text
forall a (f :: * -> *). Show a => Mod f a
showDefault
      )
    Parser
  (URI
   -> Text -> Text -> LicenseId -> FilePath -> Year -> Configuration)
-> Parser URI
-> Parser
     (Text -> Text -> LicenseId -> FilePath -> Year -> Configuration)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadM URI -> Mod OptionFields URI -> Parser URI
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
      ((FilePath -> Maybe URI) -> ReadM URI
forall a. (FilePath -> Maybe a) -> ReadM a
maybeReader FilePath -> Maybe URI
parseURI)
      ( FilePath -> Mod OptionFields URI
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"homepage"
          Mod OptionFields URI
-> Mod OptionFields URI -> Mod OptionFields URI
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields URI
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Homepage of the new project."
          Mod OptionFields URI
-> Mod OptionFields URI -> Mod OptionFields URI
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields URI
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"URL"
          Mod OptionFields URI
-> Mod OptionFields URI -> Mod OptionFields URI
forall a. Semigroup a => a -> a -> a
<> URI -> Mod OptionFields URI
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (Defaults -> URI
dHomePage Defaults
ds)
          Mod OptionFields URI
-> Mod OptionFields URI -> Mod OptionFields URI
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields URI
forall a (f :: * -> *). Show a => Mod f a
showDefault
      )
    Parser
  (Text -> Text -> LicenseId -> FilePath -> Year -> Configuration)
-> Parser Text
-> Parser (Text -> LicenseId -> FilePath -> Year -> Configuration)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption
      ( FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"author"
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Name of the author of the project."
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"AUTHOR"
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> Text -> Mod OptionFields Text
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value Text
dAuthor
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields Text
forall a (f :: * -> *). Show a => Mod f a
showDefault
      )
    Parser (Text -> LicenseId -> FilePath -> Year -> Configuration)
-> Parser Text
-> Parser (LicenseId -> FilePath -> Year -> Configuration)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption
      ( FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"maintainer"
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Email of the maintainer of the project."
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"MAINTAINER"
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> Text -> Mod OptionFields Text
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value Text
dMaintainer
          Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields Text
forall a (f :: * -> *). Show a => Mod f a
showDefault
      )
    Parser (LicenseId -> FilePath -> Year -> Configuration)
-> Parser LicenseId -> Parser (FilePath -> Year -> Configuration)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadM LicenseId -> Mod OptionFields LicenseId -> Parser LicenseId
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
      ReadM LicenseId
forall a. Read a => ReadM a
auto
      ( FilePath -> Mod OptionFields LicenseId
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"licence"
          Mod OptionFields LicenseId
-> Mod OptionFields LicenseId -> Mod OptionFields LicenseId
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields LicenseId
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Licence of the project."
          Mod OptionFields LicenseId
-> Mod OptionFields LicenseId -> Mod OptionFields LicenseId
forall a. Semigroup a => a -> a -> a
<> LicenseId -> Mod OptionFields LicenseId
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value LicenseId
Unlicense
          Mod OptionFields LicenseId
-> Mod OptionFields LicenseId -> Mod OptionFields LicenseId
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields LicenseId
forall a (f :: * -> *). Show a => Mod f a
showDefault
          Mod OptionFields LicenseId
-> Mod OptionFields LicenseId -> Mod OptionFields LicenseId
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields LicenseId
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"LICENCE"
      )
    Parser (FilePath -> Year -> Configuration)
-> Parser FilePath -> Parser (Year -> Configuration)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadM FilePath -> Mod OptionFields FilePath -> Parser FilePath
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
      ReadM FilePath
forall a. Read a => ReadM a
auto
      ( FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"path"
          Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Project path.  Only used for testing."
          Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value FilePath
dPath
          Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields FilePath
forall a (f :: * -> *). Show a => Mod f a
showDefault
          Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"PATH"
          Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields FilePath
forall (f :: * -> *) a. Mod f a
hidden
          Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields FilePath
forall (f :: * -> *) a. Mod f a
internal
      )
    Parser (Year -> Configuration)
-> Parser Year -> Parser Configuration
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadM Year -> Mod OptionFields Year -> Parser Year
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
      ReadM Year
forall a. Read a => ReadM a
auto
      ( FilePath -> Mod OptionFields Year
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"year"
          Mod OptionFields Year
-> Mod OptionFields Year -> Mod OptionFields Year
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Year
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Copyright year.  Only used for testing."
          Mod OptionFields Year
-> Mod OptionFields Year -> Mod OptionFields Year
forall a. Semigroup a => a -> a -> a
<> Year -> Mod OptionFields Year
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value Year
dYear
          Mod OptionFields Year
-> Mod OptionFields Year -> Mod OptionFields Year
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields Year
forall a (f :: * -> *). Show a => Mod f a
showDefault
          Mod OptionFields Year
-> Mod OptionFields Year -> Mod OptionFields Year
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Year
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"YEAR"
          Mod OptionFields Year
-> Mod OptionFields Year -> Mod OptionFields Year
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields Year
forall (f :: * -> *) a. Mod f a
hidden
          Mod OptionFields Year
-> Mod OptionFields Year -> Mod OptionFields Year
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields Year
forall (f :: * -> *) a. Mod f a
internal
      )