module Chiasma.Command.Session where

import Chiasma.Codec.Data.Client (Client (Client))
import Chiasma.Codec.Data.Session (Session (Session))
import Chiasma.Data.Ident (Ident)
import Chiasma.Data.SessionParams (name)
import qualified Chiasma.Data.Target as Target
import Chiasma.Data.TmuxCommand (TmuxCommand (ListClients, ListSessions, NewSession, SwitchClient))
import Chiasma.Data.TmuxError (TmuxError (NoClients))
import Chiasma.Data.TmuxId (SessionId)
import qualified Chiasma.Effect.TmuxApi as Tmux
import Chiasma.Effect.TmuxApi (Tmux)

sameId :: SessionId -> Session -> Bool
sameId :: SessionId -> Session -> Bool
sameId SessionId
target (Session SessionId
i Text
_) = SessionId
target SessionId -> SessionId -> Bool
forall a. Eq a => a -> a -> Bool
== SessionId
i

sessions ::
  Member Tmux r =>
  Sem r [Session]
sessions :: forall (r :: EffectRow). Member Tmux r => Sem r [Session]
sessions =
  TmuxCommand [Session] -> Sem r [Session]
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send TmuxCommand [Session]
ListSessions

doesSessionExist ::
  Member Tmux r =>
  SessionId ->
  Sem r Bool
doesSessionExist :: forall (r :: EffectRow). Member Tmux r => SessionId -> Sem r Bool
doesSessionExist SessionId
sessionId =
  (Session -> Bool) -> [Session] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (SessionId -> Session -> Bool
sameId SessionId
sessionId) ([Session] -> Bool) -> Sem r [Session] -> Sem r Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sem r [Session]
forall (r :: EffectRow). Member Tmux r => Sem r [Session]
sessions

existingSessionId ::
  Member Tmux r =>
  SessionId ->
  Sem r (Maybe SessionId)
existingSessionId :: forall (r :: EffectRow).
Member Tmux r =>
SessionId -> Sem r (Maybe SessionId)
existingSessionId SessionId
sessionId = do
  Bool
exists <- SessionId -> Sem r Bool
forall (r :: EffectRow). Member Tmux r => SessionId -> Sem r Bool
doesSessionExist SessionId
sessionId
  pure $ if Bool
exists then SessionId -> Maybe SessionId
forall a. a -> Maybe a
Just SessionId
sessionId else Maybe SessionId
forall a. Maybe a
Nothing

newSession ::
  Member Tmux r =>
  Ident ->
  Sem r Session
newSession :: forall (r :: EffectRow). Member Tmux r => Ident -> Sem r Session
newSession Ident
name =
  TmuxCommand Session -> Sem r Session
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (SessionParams -> TmuxCommand Session
NewSession SessionParams
forall a. Default a => a
def { $sel:name:SessionParams :: Maybe Ident
name = Ident -> Maybe Ident
forall a. a -> Maybe a
Just Ident
name })

clientForSession :: SessionId -> [Client] -> Maybe Client
clientForSession :: SessionId -> [Client] -> Maybe Client
clientForSession SessionId
session =
  (Client -> Bool) -> [Client] -> Maybe Client
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find \case
    Client ClientId
_ Bool
False SessionId
sid ->
      SessionId
sid SessionId -> SessionId -> Bool
forall a. Eq a => a -> a -> Bool
== SessionId
session
    Client
_ ->
      Bool
False

switchClient ::
  Members [Tmux, Stop TmuxError] r =>
  SessionId ->
  SessionId ->
  Sem r ()
switchClient :: forall (r :: EffectRow).
Members '[Tmux, Stop TmuxError] r =>
SessionId -> SessionId -> Sem r ()
switchClient SessionId
clientSession SessionId
session = do
  [Client]
clients <- TmuxCommand [Client] -> Sem r [Client]
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send TmuxCommand [Client]
ListClients
  Client ClientId
client Bool
_ SessionId
_ <- TmuxError -> Maybe Client -> Sem r Client
forall err (r :: EffectRow) a.
Member (Stop err) r =>
err -> Maybe a -> Sem r a
stopNote TmuxError
NoClients (SessionId -> [Client] -> Maybe Client
clientForSession SessionId
clientSession [Client]
clients)
  TmuxCommand () -> Sem r ()
forall (command :: * -> *) (r :: EffectRow) a.
Member (TmuxApi command) r =>
command a -> Sem r a
Tmux.send (ClientId -> Target -> TmuxCommand ()
SwitchClient ClientId
client (SessionId -> Target
Target.Session SessionId
session))