{-# LANGUAGE QuasiQuotes #-}
-- | Case study variants.
--
-- Each case study is expected to generate files in a specific pattern that the
-- main `code/Makefile` expects for (a) testing and (b) website deployment.
module Drasil.Generator.CaseStudyVariants
  ( caseStudyMainSRS,
    caseStudyMainSRSWCode,
    caseStudyMainSRSWCodeZoo,
  )
where

import Control.Lens ((^.))

import Drasil.FileHandling (FileLayout, OverwritePolicy(..), directory, localPath, ps,
  writeFiles)
import Drasil.SRS (SRSDecl, SmithEtAlSRS, genSmithEtAlSrs, typeCheckSI)
import Language.Drasil.Code (Choices)

import Drasil.Generator.Code (genCode, genCodeZoo)
import Drasil.Generator.WriteSystem (setSystemLocale)
import Drasil.System (HasProjectName(..))

-- | Internal: Generate documents and construct the SRS directory layout
-- structure (and debug data) for an example.
writeSmithEtAlSrs :: SmithEtAlSRS -> SRSDecl -> String -> IO [FileLayout]
writeSmithEtAlSrs :: SmithEtAlSRS -> SRSDecl -> String -> IO [FileLayout]
writeSmithEtAlSrs SmithEtAlSRS
syst SRSDecl
srsDecl String
srsFileName = do
  SmithEtAlSRS -> IO ()
typeCheckSI SmithEtAlSRS
syst -- FIXME: This should be done on `System` creation *or* chunk creation!
  [FileLayout] -> IO [FileLayout]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([FileLayout] -> IO [FileLayout])
-> [FileLayout] -> IO [FileLayout]
forall a b. (a -> b) -> a -> b
$ SmithEtAlSRS -> SRSDecl -> String -> [FileLayout]
genSmithEtAlSrs SmithEtAlSRS
syst SRSDecl
srsDecl String
srsFileName

-- | A case study that only outputs an SRS in each of our supported variants.
caseStudyMainSRS :: SmithEtAlSRS -> SRSDecl -> String -> IO ()
caseStudyMainSRS :: SmithEtAlSRS -> SRSDecl -> String -> IO ()
caseStudyMainSRS SmithEtAlSRS
syst SRSDecl
srsDecl String
srsFileName = do
  IO ()
setSystemLocale
  let exampleName :: String
exampleName = SmithEtAlSRS
syst SmithEtAlSRS -> Getting String SmithEtAlSRS String -> String
forall s a. s -> Getting a s a -> a
^. Getting String SmithEtAlSRS String
forall c. HasProjectName c => Lens' c String
Lens' SmithEtAlSRS String
projRepoName
  docLayouts <- SmithEtAlSRS -> SRSDecl -> String -> IO [FileLayout]
writeSmithEtAlSrs SmithEtAlSRS
syst SRSDecl
srsDecl String
srsFileName
  writeFiles OverwriteAllowed localPath $ directory [ps|{exampleName}|] docLayouts

-- | A case study that outputs both an SRS in each of our supported variants as
-- well as a single chosen software artifact in optionally many programming
-- languages.
caseStudyMainSRSWCode :: SmithEtAlSRS -> SRSDecl -> String -> Choices -> IO ()
caseStudyMainSRSWCode :: SmithEtAlSRS -> SRSDecl -> String -> Choices -> IO ()
caseStudyMainSRSWCode SmithEtAlSRS
syst SRSDecl
srsDecl String
srsFileName Choices
choices = do
  IO ()
setSystemLocale
  let exampleName :: String
exampleName = SmithEtAlSRS
syst SmithEtAlSRS -> Getting String SmithEtAlSRS String -> String
forall s a. s -> Getting a s a -> a
^. Getting String SmithEtAlSRS String
forall c. HasProjectName c => Lens' c String
Lens' SmithEtAlSRS String
projRepoName
  docLayouts <- SmithEtAlSRS -> SRSDecl -> String -> IO [FileLayout]
writeSmithEtAlSrs SmithEtAlSRS
syst SRSDecl
srsDecl String
srsFileName
  srcLayout <- genCode syst choices
  writeFiles OverwriteAllowed localPath $ directory [ps|{exampleName}|] $ srcLayout : docLayouts

-- | The same as 'caseStudyMainSRSWCode', except it also produces a
-- JupyterNotebook-based lesson plan.
caseStudyMainSRSWCodeZoo :: SmithEtAlSRS -> SRSDecl -> String -> [Choices] -> IO ()
caseStudyMainSRSWCodeZoo :: SmithEtAlSRS -> SRSDecl -> String -> [Choices] -> IO ()
caseStudyMainSRSWCodeZoo SmithEtAlSRS
syst SRSDecl
srsDecl String
srsFileName [Choices]
choices = do
  IO ()
setSystemLocale
  let exampleName :: String
exampleName = SmithEtAlSRS
syst SmithEtAlSRS -> Getting String SmithEtAlSRS String -> String
forall s a. s -> Getting a s a -> a
^. Getting String SmithEtAlSRS String
forall c. HasProjectName c => Lens' c String
Lens' SmithEtAlSRS String
projRepoName
  docLayouts <- SmithEtAlSRS -> SRSDecl -> String -> IO [FileLayout]
writeSmithEtAlSrs SmithEtAlSRS
syst SRSDecl
srsDecl String
srsFileName
  zooLayouts <- genCodeZoo syst choices
  let layout = PathSegment -> [FileLayout] -> FileLayout
forall (f :: * -> *).
Foldable f =>
PathSegment -> f FileLayout -> FileLayout
directory [ps|{exampleName}|] ([FileLayout] -> FileLayout) -> [FileLayout] -> FileLayout
forall a b. (a -> b) -> a -> b
$ [FileLayout]
docLayouts [FileLayout] -> [FileLayout] -> [FileLayout]
forall a. [a] -> [a] -> [a]
++ [FileLayout]
zooLayouts
  writeFiles OverwriteAllowed localPath layout