{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}

-- | Provides the 'Command' type.
module Charon.Runner.Command
  ( -- * Types
    Command (..),
    CommandP1,
    CommandP2,

    -- * Optics
    _Delete,
    _PermDelete,
    _Empty,
    _Restore,
    _List,
    _Metadata,
  )
where

import Charon.Backend.Data (Backend)
import Charon.Data.Paths
  ( PathI,
    PathIndex
      ( TrashEntryFileName,
        TrashEntryOriginalPath,
        TrashHome
      ),
  )
import Charon.Data.UniqueSeqNE (UniqueSeqNE)
import Charon.Prelude
import Charon.Runner.Command.List (ListCmd)
import Charon.Runner.Phase (AdvancePhase (..), Phase (..))

instance AdvancePhase (Command Phase1) where
  type NextPhase (Command Phase1) = Command Phase2

  advancePhase :: Command 'Phase1 -> NextPhase (Command 'Phase1)
advancePhase (Delete UniqueSeqNE (PathI 'TrashEntryOriginalPath)
paths) = UniqueSeqNE (PathI 'TrashEntryOriginalPath) -> Command 'Phase2
forall (s :: Phase).
UniqueSeqNE (PathI 'TrashEntryOriginalPath) -> Command s
Delete UniqueSeqNE (PathI 'TrashEntryOriginalPath)
paths
  advancePhase (PermDelete Bool
force UniqueSeqNE (PathI 'TrashEntryFileName)
paths) = Bool -> UniqueSeqNE (PathI 'TrashEntryFileName) -> Command 'Phase2
forall (s :: Phase).
Bool -> UniqueSeqNE (PathI 'TrashEntryFileName) -> Command s
PermDelete Bool
force UniqueSeqNE (PathI 'TrashEntryFileName)
paths
  advancePhase (Empty Bool
b) = Bool -> Command 'Phase2
forall (s :: Phase). Bool -> Command s
Empty Bool
b
  advancePhase (Restore UniqueSeqNE (PathI 'TrashEntryFileName)
paths) = UniqueSeqNE (PathI 'TrashEntryFileName) -> Command 'Phase2
forall (s :: Phase).
UniqueSeqNE (PathI 'TrashEntryFileName) -> Command s
Restore UniqueSeqNE (PathI 'TrashEntryFileName)
paths
  advancePhase Command 'Phase1
Metadata = NextPhase (Command 'Phase1)
Command 'Phase2
forall (s :: Phase). Command s
Metadata
  advancePhase (List ListCmd 'Phase1
cfg) = ListCmd 'Phase2 -> Command 'Phase2
forall (s :: Phase). ListCmd s -> Command s
List (ListCmd 'Phase2 -> Command 'Phase2)
-> ListCmd 'Phase2 -> Command 'Phase2
forall a b. (a -> b) -> a -> b
$ ListCmd 'Phase1 -> NextPhase (ListCmd 'Phase1)
forall a. AdvancePhase a => a -> NextPhase a
advancePhase ListCmd 'Phase1
cfg
  advancePhase (Convert Backend
dest) = Backend -> Command 'Phase2
forall (s :: Phase). Backend -> Command s
Convert Backend
dest
  advancePhase (Merge PathI 'TrashHome
dest) = PathI 'TrashHome -> Command 'Phase2
forall (s :: Phase). PathI 'TrashHome -> Command s
Merge PathI 'TrashHome
dest

-- | Action to run.
type Command :: Phase -> Type
data Command s
  = -- | Deletes a path.
    Delete (UniqueSeqNE (PathI TrashEntryOriginalPath))
  | -- | Permanently deletes a path from the trash.
    PermDelete
      Bool
      (UniqueSeqNE (PathI TrashEntryFileName))
  | -- | Empties the trash.
    Empty Bool
  | -- | Restores a path.
    Restore (UniqueSeqNE (PathI TrashEntryFileName))
  | -- | List all trash contents.
    List (ListCmd s)
  | -- | Prints trash metadata.
    Metadata
  | -- | Converts backend files.
    Convert Backend
  | -- | Merges trash home directories.
    Merge (PathI TrashHome)

makePrisms ''Command

deriving stock instance Eq (Command Phase1)

deriving stock instance Show (Command Phase1)

deriving stock instance Eq (Command Phase2)

deriving stock instance Show (Command Phase2)

type CommandP1 = Command Phase1

type CommandP2 = Command Phase2