{- |
Module:      PFile.CLI.New
Copyright:   (c) 2024 Illia Shkroba
License:     BSD3
Maintainer:  Illia Shkroba <is@pjwstk.edu.pl>
Stability:   unstable
Portability: non-portable (Non-Unix systems are not supported)

Options for `pfile new`.
-}

{-# LANGUAGE ApplicativeDo   #-}
{-# LANGUAGE RecordWildCards #-}

module PFile.CLI.New
  ( parserInfo
  , parser
  , Options (..)
  ) where

import           Options.Applicative
  ( Parser
  , ParserInfo
  , action
  , argument
  , flag
  , fullDesc
  , header
  , help
  , helper
  , info
  , long
  , metavar
  , progDesc
  , short
  , str
  )
import qualified PFile.Profile.LinkHandling as LinkHandling
import           Protolude

parserInfo :: ParserInfo Options
parserInfo :: ParserInfo Options
parserInfo = Parser Options -> InfoMod Options -> ParserInfo Options
forall a. Parser a -> InfoMod a -> ParserInfo a
info (Parser Options
parser Parser Options -> Parser (Options -> Options) -> Parser Options
forall (f :: * -> *) a b. Applicative f => f a -> f (a -> b) -> f b
<**> Parser (Options -> Options)
forall a. Parser (a -> a)
helper)
  (InfoMod Options -> ParserInfo Options)
-> InfoMod Options -> ParserInfo Options
forall a b. (a -> b) -> a -> b
$  InfoMod Options
forall a. InfoMod a
fullDesc
  InfoMod Options -> InfoMod Options -> InfoMod Options
forall a. Semigroup a => a -> a -> a
<> FilePath -> InfoMod Options
forall a. FilePath -> InfoMod a
header FilePath
"pfile new - create a new PROFILE for a set of OBJECTS"
  InfoMod Options -> InfoMod Options -> InfoMod Options
forall a. Semigroup a => a -> a -> a
<> FilePath -> InfoMod Options
forall a. FilePath -> InfoMod a
progDesc FilePath
description
  where
    description :: FilePath
description
      =  FilePath
"Create a PROFILE with a set of OBJECTS moved into it. After PROFILE's"
      FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" creation, entries origins (\"OBJECTS...\") are removed. Current"
      FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" profile (set with `pfile switch`) is always reverted afterwards. So"
      FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" if one of the OBJECTS is a link pointing at current profile's entry,"
      FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" the link will be recovered. By default when an entry is a link, the"
      FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" target of the link is copied into the PROFILE. When `--empty` flag"
      FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" is passed and an entry is a link, an empty entry is created in the"
      FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" PROFILE."

parser :: Parser Options
parser :: Parser Options
parser = do
  Strategy
linkHandlingStrategy <- Strategy -> Strategy -> Mod FlagFields Strategy -> Parser Strategy
forall a. a -> a -> Mod FlagFields a -> Parser a
flag Strategy
LinkHandling.CopyFromOrigin Strategy
LinkHandling.CreateEmpty
    (Mod FlagFields Strategy -> Parser Strategy)
-> Mod FlagFields Strategy -> Parser Strategy
forall a b. (a -> b) -> a -> b
$  Char -> Mod FlagFields Strategy
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'e'
    Mod FlagFields Strategy
-> Mod FlagFields Strategy -> Mod FlagFields Strategy
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod FlagFields Strategy
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"empty"
    Mod FlagFields Strategy
-> Mod FlagFields Strategy -> Mod FlagFields Strategy
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod FlagFields Strategy
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Make empty entries in PROFILE instead of copying links targets"
  Text
profileName <- ReadM Text -> Mod ArgumentFields Text -> Parser Text
forall a. ReadM a -> Mod ArgumentFields a -> Parser a
argument ReadM Text
forall s. IsString s => ReadM s
str (FilePath -> Mod ArgumentFields Text
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"PROFILE")
  [FilePath]
paths <- Parser FilePath -> Parser [FilePath]
forall a. Parser a -> Parser [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Parser FilePath -> Parser [FilePath])
-> Parser FilePath -> Parser [FilePath]
forall a b. (a -> b) -> a -> b
$ ReadM FilePath -> Mod ArgumentFields FilePath -> Parser FilePath
forall a. ReadM a -> Mod ArgumentFields a -> Parser a
argument ReadM FilePath
forall s. IsString s => ReadM s
str (FilePath -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"OBJECTS..." Mod ArgumentFields FilePath
-> Mod ArgumentFields FilePath -> Mod ArgumentFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. HasCompleter f => FilePath -> Mod f a
action FilePath
"file")
  pure Options {[FilePath]
Text
Strategy
linkHandlingStrategy :: Strategy
profileName :: Text
paths :: [FilePath]
linkHandlingStrategy :: Strategy
profileName :: Text
paths :: [FilePath]
..}

data Options
  = Options
      { Options -> Strategy
linkHandlingStrategy :: !LinkHandling.Strategy
      , Options -> Text
profileName          :: !Text
      , Options -> [FilePath]
paths                :: ![FilePath]
      }