{-# LANGUAGE TemplateHaskell #-}

-- | Defines a package extension for GOOL, with the relevant slice of GOOLState
-- and functions for pairing a GOOL program with
-- "Software Dossier" (i.e. non-source-code) files.
module Language.Drasil.SoftwareDossier.SoftwareDossierSym (
  -- DataTypes
  SoftwareDossierState, makeSds, headers, sources, mainMod,
  -- Typeclasses
  SoftwareDossierSym(..),
  -- Functions
  sampleInput, sdsFromData
) where

import Text.PrettyPrint.HughesPJ (Doc)

import Utils.Drasil.FileData (FileAndContents(..), fileAndContents)
import Drasil.GOOL (ProgData)
import Language.Drasil.Printers (PrintingInformation)

import Language.Drasil (Expr)
import Language.Drasil.Code.DataDesc (DataDesc)
import Language.Drasil.SoftwareDossier.FileNames (sampleInputName)
import Language.Drasil.Choices (Comments, ImplementationType, Verbosity)
import Language.Drasil.Code.Imperative.WriteInput (makeInputFile)
import Language.Drasil.Code.Imperative.README (ReadMeInfo(..))

import Control.Lens (makeLenses)

data SoftwareDossierState = Sds {
  SoftwareDossierState -> [FilePath]
_headers :: [FilePath], -- Used by Drasil for doxygen config gen
  SoftwareDossierState -> [FilePath]
_sources :: [FilePath], -- Used by Drasil for doxygen config and Makefile gen
  SoftwareDossierState -> Maybe FilePath
_mainMod :: Maybe FilePath -- Used by Drasil generator to access main
                             -- mod file path (needed in Makefile generation)
}
makeLenses ''SoftwareDossierState

makeSds :: [FilePath] -> [FilePath] -> Maybe FilePath -> SoftwareDossierState
makeSds :: [FilePath] -> [FilePath] -> Maybe FilePath -> SoftwareDossierState
makeSds [FilePath]
headerFiles [FilePath]
sourceFiles Maybe FilePath
mainModule = Sds {
    _headers :: [FilePath]
_headers = [FilePath]
headerFiles,
    _sources :: [FilePath]
_sources = [FilePath]
sourceFiles,
    _mainMod :: Maybe FilePath
_mainMod = Maybe FilePath
mainModule
  }

-- | Members of this class must have a doxygen configuration, ReadMe file,
-- omptimize doxygen document, information necessary for a makefile, and
-- auxiliary helper documents
class SoftwareDossierSym r where
  doxConfig :: String -> SoftwareDossierState -> Verbosity -> r FileAndContents
  readMe ::  ReadMeInfo -> r FileAndContents

  optimizeDox :: r Doc

  makefile :: [FilePath] -> ImplementationType -> [Comments] -> SoftwareDossierState ->
    ProgData -> r FileAndContents

  unReprDoc :: r Doc -> Doc

sampleInput :: (Applicative r) => PrintingInformation -> DataDesc -> [Expr] ->
  r FileAndContents
sampleInput :: forall (r :: * -> *).
Applicative r =>
PrintingInformation -> DataDesc -> [Expr] -> r FileAndContents
sampleInput PrintingInformation
db DataDesc
d [Expr]
sd = FilePath -> Doc -> r FileAndContents
forall (r :: * -> *).
Applicative r =>
FilePath -> Doc -> r FileAndContents
sdsFromData FilePath
sampleInputName (PrintingInformation -> DataDesc -> [Expr] -> Doc
makeInputFile PrintingInformation
db DataDesc
d [Expr]
sd)

sdsFromData :: Applicative r => FilePath -> Doc -> r FileAndContents
sdsFromData :: forall (r :: * -> *).
Applicative r =>
FilePath -> Doc -> r FileAndContents
sdsFromData FilePath
fp Doc
d = FileAndContents -> r FileAndContents
forall a. a -> r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FileAndContents -> r FileAndContents)
-> FileAndContents -> r FileAndContents
forall a b. (a -> b) -> a -> b
$ FilePath -> Doc -> FileAndContents
fileAndContents FilePath
fp Doc
d