{-# LANGUAGE TypeFamilies #-}

-- | The logic to render Python auxiliary files is contained in this module
module Language.Drasil.Code.Imperative.GOOL.LanguageRenderer.PythonRenderer (
  PythonProject(..)
) where

import Language.Drasil.Code.Imperative.GOOL.ClassInterface (ReadMeInfo(..),PackageSym(..), 
  AuxiliarySym(..))
import qualified 
  Language.Drasil.Code.Imperative.GOOL.LanguageRenderer.LanguagePolymorphic as 
  G (doxConfig, readMe, sampleInput, makefile, noRunIfLib, doxDocConfig, 
  docIfEnabled)
import Language.Drasil.Code.Imperative.GOOL.Data (AuxData(..), ad, PackData(..),
  packD)
import Language.Drasil.Code.Imperative.Build.AST (Runnable, interpMM)
import Language.Drasil.Code.Imperative.Doxygen.Import (yes)

import GOOL.Drasil (onCodeList, pyName, pyVersion)

import Prelude hiding (break,print,sin,cos,tan,floor,(<>))
import Text.PrettyPrint.HughesPJ (Doc)

-- | Holds a Python project.
newtype PythonProject a = PP {PythonProject a -> a
unPP :: a}

instance Functor PythonProject where
  fmap :: (a -> b) -> PythonProject a -> PythonProject b
fmap f :: a -> b
f (PP x :: a
x) = b -> PythonProject b
forall a. a -> PythonProject a
PP (a -> b
f a
x)

instance Applicative PythonProject where
  pure :: a -> PythonProject a
pure = a -> PythonProject a
forall a. a -> PythonProject a
PP
  (PP f :: a -> b
f) <*> :: PythonProject (a -> b) -> PythonProject a -> PythonProject b
<*> (PP x :: a
x) = b -> PythonProject b
forall a. a -> PythonProject a
PP (a -> b
f a
x)

instance Monad PythonProject where
  return :: a -> PythonProject a
return = a -> PythonProject a
forall a. a -> PythonProject a
PP
  PP x :: a
x >>= :: PythonProject a -> (a -> PythonProject b) -> PythonProject b
>>= f :: a -> PythonProject b
f = a -> PythonProject b
f a
x

instance PackageSym PythonProject where
  type Package PythonProject = PackData
  package :: ProgData
-> [PythonProject (Auxiliary PythonProject)]
-> PythonProject (Package PythonProject)
package p :: ProgData
p = ([AuxData] -> PackData)
-> [PythonProject AuxData] -> PythonProject PackData
forall (m :: * -> *) a b. Monad m => ([a] -> b) -> [m a] -> m b
onCodeList (ProgData -> [AuxData] -> PackData
packD ProgData
p)

instance AuxiliarySym PythonProject where
  type Auxiliary PythonProject = AuxData
  type AuxHelper PythonProject = Doc
  doxConfig :: String
-> GOOLState
-> Verbosity
-> PythonProject (Auxiliary PythonProject)
doxConfig = PythonProject (AuxHelper PythonProject)
-> String
-> GOOLState
-> Verbosity
-> PythonProject (Auxiliary PythonProject)
forall (r :: * -> *).
AuxiliarySym r =>
r (AuxHelper r)
-> String -> GOOLState -> Verbosity -> r (Auxiliary r)
G.doxConfig PythonProject (AuxHelper PythonProject)
forall (r :: * -> *). AuxiliarySym r => r (AuxHelper r)
optimizeDox
  readMe :: ReadMeInfo -> PythonProject (Auxiliary PythonProject)
readMe rmi :: ReadMeInfo
rmi =
    ReadMeInfo -> PythonProject (Auxiliary PythonProject)
forall (r :: * -> *).
AuxiliarySym r =>
ReadMeInfo -> r (Auxiliary r)
G.readMe ReadMeInfo
rmi {
        langName :: String
langName = String
pyName,
        langVersion :: String
langVersion = String
pyVersion}
  sampleInput :: ChunkDB
-> DataDesc -> [Expr] -> PythonProject (Auxiliary PythonProject)
sampleInput = ChunkDB
-> DataDesc -> [Expr] -> PythonProject (Auxiliary PythonProject)
forall (r :: * -> *).
AuxiliarySym r =>
ChunkDB -> DataDesc -> [Expr] -> r (Auxiliary r)
G.sampleInput

  optimizeDox :: PythonProject (AuxHelper PythonProject)
optimizeDox = Doc -> PythonProject Doc
forall (m :: * -> *) a. Monad m => a -> m a
return Doc
yes

  makefile :: [String]
-> ImplementationType
-> [Comments]
-> GOOLState
-> ProgData
-> PythonProject (Auxiliary PythonProject)
makefile _ it :: ImplementationType
it cms :: [Comments]
cms = Maybe BuildConfig
-> Maybe Runnable
-> Maybe DocConfig
-> GOOLState
-> ProgData
-> PythonProject (Auxiliary PythonProject)
forall (r :: * -> *).
AuxiliarySym r =>
Maybe BuildConfig
-> Maybe Runnable
-> Maybe DocConfig
-> GOOLState
-> ProgData
-> r (Auxiliary r)
G.makefile Maybe BuildConfig
forall a. Maybe a
Nothing (ImplementationType -> Maybe Runnable -> Maybe Runnable
G.noRunIfLib ImplementationType
it Maybe Runnable
pyRunnable)
    ([Comments] -> DocConfig -> Maybe DocConfig
G.docIfEnabled [Comments]
cms DocConfig
G.doxDocConfig)

  auxHelperDoc :: PythonProject (AuxHelper PythonProject) -> Doc
auxHelperDoc = PythonProject (AuxHelper PythonProject) -> Doc
forall a. PythonProject a -> a
unPP
  auxFromData :: String -> Doc -> PythonProject (Auxiliary PythonProject)
auxFromData fp :: String
fp d :: Doc
d = AuxData -> PythonProject (Auxiliary PythonProject)
forall (m :: * -> *) a. Monad m => a -> m a
return (AuxData -> PythonProject (Auxiliary PythonProject))
-> AuxData -> PythonProject (Auxiliary PythonProject)
forall a b. (a -> b) -> a -> b
$ String -> Doc -> AuxData
ad String
fp Doc
d

-- | Default runnable information for Python files.
pyRunnable :: Maybe Runnable
pyRunnable :: Maybe Runnable
pyRunnable = String -> Maybe Runnable
interpMM "python"