{-# LANGUAGE DeriveGeneric #-}

-- |
-- Module      :  SLynx.Translate.Options
-- Description :  ELynxSeq argument parsing
-- Copyright   :  2021 Dominik Schrempf
-- License     :  GPL-3.0-or-later
--
-- Maintainer  :  dominik.schrempf@gmail.com
-- Stability   :  unstable
-- Portability :  portable
--
-- Creation date: Sun Oct  7 17:29:45 2018.
module SLynx.Translate.Options
  ( TranslateArguments (..),
    translateArguments,
  )
where

import Data.Aeson
import Data.List
import ELynx.Alphabet.Alphabet
import ELynx.Character.Codon
import ELynx.Tools.Reproduction
import GHC.Generics
import Options.Applicative
import SLynx.Tools

-- | Arguments needed to translate sequences.
data TranslateArguments = TranslateArguments
  { TranslateArguments -> Alphabet
trAlphabet :: Alphabet,
    TranslateArguments -> FilePath
trInFile :: FilePath,
    TranslateArguments -> Int
trReadingFrame :: Int,
    TranslateArguments -> UniversalCode
trUniversalCode :: UniversalCode
  }
  deriving (TranslateArguments -> TranslateArguments -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TranslateArguments -> TranslateArguments -> Bool
$c/= :: TranslateArguments -> TranslateArguments -> Bool
== :: TranslateArguments -> TranslateArguments -> Bool
$c== :: TranslateArguments -> TranslateArguments -> Bool
Eq, Int -> TranslateArguments -> ShowS
[TranslateArguments] -> ShowS
TranslateArguments -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [TranslateArguments] -> ShowS
$cshowList :: [TranslateArguments] -> ShowS
show :: TranslateArguments -> FilePath
$cshow :: TranslateArguments -> FilePath
showsPrec :: Int -> TranslateArguments -> ShowS
$cshowsPrec :: Int -> TranslateArguments -> ShowS
Show, forall x. Rep TranslateArguments x -> TranslateArguments
forall x. TranslateArguments -> Rep TranslateArguments x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TranslateArguments x -> TranslateArguments
$cfrom :: forall x. TranslateArguments -> Rep TranslateArguments x
Generic)

instance Reproducible TranslateArguments where
  inFiles :: TranslateArguments -> [FilePath]
inFiles = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. TranslateArguments -> FilePath
trInFile
  outSuffixes :: TranslateArguments -> [FilePath]
outSuffixes TranslateArguments
_ = [FilePath
".fasta"]
  getSeed :: TranslateArguments -> Maybe SeedOpt
getSeed TranslateArguments
_ = forall a. Maybe a
Nothing
  setSeed :: TranslateArguments -> SeedOpt -> TranslateArguments
setSeed = forall a b. a -> b -> a
const
  parser :: Parser TranslateArguments
parser = Parser TranslateArguments
translateArguments
  cmdName :: FilePath
cmdName = FilePath
"translate"
  cmdDsc :: [FilePath]
cmdDsc = [FilePath
"Translate from DNA to Protein or DNAX to ProteinX."]

instance FromJSON TranslateArguments

instance ToJSON TranslateArguments

-- | Command line parser.
translateArguments :: Parser TranslateArguments
translateArguments :: Parser TranslateArguments
translateArguments =
  Alphabet -> FilePath -> Int -> UniversalCode -> TranslateArguments
TranslateArguments
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Alphabet
alphabetOpt
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser FilePath
inFileArg
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Int
readingFrameOpt
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser UniversalCode
universalCodeOpt

readingFrameOpt :: Parser Int
readingFrameOpt :: Parser Int
readingFrameOpt =
  forall a. ReadM a -> Mod OptionFields a -> Parser a
option forall a. Read a => ReadM a
auto forall a b. (a -> b) -> a -> b
$
    forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"reading-frame"
      forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'r'
      forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"INT"
      forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. FilePath -> Mod f a
help
        FilePath
"Reading frame [0|1|2]."

universalCodeOpt :: Parser UniversalCode
universalCodeOpt :: Parser UniversalCode
universalCodeOpt =
  forall a. ReadM a -> Mod OptionFields a -> Parser a
option forall a. Read a => ReadM a
auto forall a b. (a -> b) -> a -> b
$
    forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"universal-code"
      forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'u'
      forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"CODE"
      forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. FilePath -> Mod f a
help
        (FilePath
"universal code; one of: " forall a. [a] -> [a] -> [a]
++ FilePath
codeStr forall a. [a] -> [a] -> [a]
++ FilePath
".")
  where
    codes :: [UniversalCode]
codes = [forall a. Bounded a => a
minBound ..] :: [UniversalCode]
    codeWords :: [FilePath]
codeWords = forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> FilePath
show [UniversalCode]
codes
    codeStr :: FilePath
codeStr = forall a. [a] -> [[a]] -> [a]
intercalate FilePath
", " [FilePath]
codeWords

inFileArg :: Parser FilePath
inFileArg :: Parser FilePath
inFileArg =
  forall s. IsString s => Mod ArgumentFields s -> Parser s
strArgument forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"INPUT-FILE" forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Read sequences from INPUT-FILE"