{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeOperators #-}

module Axel.Eff.Resource where

import Axel.Eff.FileSystem as FS (FileSystem, readFile)

import Control.Monad ((>=>))
import Control.Monad.Freer
  ( type (~>)
  , Eff
  , LastMember
  , Member
  , Members
  , interpretM
  , send
  )

import Paths_axel (getDataFileName)

import System.FilePath ((</>))

newtype ResourceId =
  ResourceId String

data Resource a where
  GetResourcePath :: ResourceId -> Resource FilePath

getResourcePath :: (Member Resource effs) => ResourceId -> Eff effs FilePath
getResourcePath = send . GetResourcePath

runEff :: (LastMember IO effs) => Eff (Resource ': effs) ~> Eff effs
runEff =
  interpretM
    (\case
       GetResourcePath (ResourceId resource) ->
         getDataFileName ("resources" </> resource))

readResource ::
     (Members '[ FileSystem, Resource] effs) => ResourceId -> Eff effs String
readResource = getResourcePath >=> FS.readFile

astDefinition :: ResourceId
astDefinition = ResourceId "autogenerated/macros/AST.hs"

macroDefinitionAndEnvironmentFooter :: ResourceId
macroDefinitionAndEnvironmentFooter =
  ResourceId "macros/MacroDefinitionAndEnvironmentFooter.hs"

macroDefinitionAndEnvironmentHeader :: ResourceId
macroDefinitionAndEnvironmentHeader =
  ResourceId "macros/MacroDefinitionAndEnvironmentHeader.hs"

macroScaffold :: ResourceId
macroScaffold = ResourceId "macros/Scaffold.hs"

newProjectTemplate :: ResourceId
newProjectTemplate = ResourceId "new-project-template"