{-# LANGUAGE QuasiQuotes #-}

-- | Provides classes for running Charon with an environment.
module Charon.Env
  ( HasTrashHome (..),
    getTrashLog,
    HasBackend (..),
  )
where

import Charon.Backend.Data (Backend)
import Charon.Data.Paths
  ( PathI (MkPathI),
    PathIndex
      ( TrashHome,
        TrashLog
      ),
  )
import Charon.Prelude
import Effects.FileSystem.PathReader (getXdgState)

-- | Class for retrieving the trash home.
class HasTrashHome a where
  -- | Retrieves the trash home path.
  getTrashHome :: a -> PathI TrashHome
  default getTrashHome ::
    ( Is k A_Getter,
      LabelOptic' "trashHome" k a (PathI TrashHome)
    ) =>
    a ->
    PathI TrashHome
  getTrashHome = Optic' k NoIx a (PathI 'TrashHome) -> a -> PathI 'TrashHome
forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' k NoIx a (PathI 'TrashHome)
#trashHome

-- | Retrieves the trash log path.
getTrashLog :: (HasCallStack, MonadPathReader m) => m (PathI TrashLog)
getTrashLog :: forall (m :: OpticKind -> OpticKind).
(HasCallStack, MonadPathReader m) =>
m (PathI 'TrashLog)
getTrashLog = OsPath -> PathI 'TrashLog
forall (i :: PathIndex). OsPath -> PathI i
MkPathI (OsPath -> PathI 'TrashLog)
-> (OsPath -> OsPath) -> OsPath -> PathI 'TrashLog
forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. (OsPath -> OsPath -> OsPath
</> [osp|charon.log|]) (OsPath -> PathI 'TrashLog) -> m OsPath -> m (PathI 'TrashLog)
forall (f :: OpticKind -> OpticKind) (a :: OpticKind)
       (b :: OpticKind).
Functor f =>
(a -> b) -> f a -> f b
<$> OsPath -> m OsPath
forall (m :: OpticKind -> OpticKind).
(HasCallStack, MonadPathReader m) =>
OsPath -> m OsPath
getXdgState OsPath
pathCharon

-- | Class for retrieving the backend.
class HasBackend a where
  -- | Retrieves the trash home path.
  getBackend :: a -> Backend
  default getBackend ::
    ( Is k A_Getter,
      LabelOptic' "backend" k a Backend
    ) =>
    a ->
    Backend
  getBackend = Optic' k NoIx a Backend -> a -> Backend
forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' k NoIx a Backend
#backend