module IHP.IDE.Logs.Controller where

import IHP.ControllerPrelude
import IHP.IDE.ToolServer.Helper.Controller
import IHP.IDE.ToolServer.Types
import IHP.IDE.Logs.View.Logs
import qualified IHP.IDE.Types as DevServer
import qualified Data.ByteString.Char8 as ByteString
import qualified Data.ByteString.Builder as ByteString

instance Controller LogsController where
    action :: (?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::LogsController) =>
LogsController -> IO ()
action LogsController
AppLogsAction = do
        AppState
currentDevServerState <- IO AppState
(?context::ControllerContext) => IO AppState
readDevServerState
        let statusServerState :: StatusServerState
statusServerState = AppState
currentDevServerState.statusServerState

        (ByteString
standardOutput, ByteString
errorOutput) <- case StatusServerState
statusServerState of
                StatusServerState
DevServer.StatusServerNotStarted -> (ByteString, ByteString) -> IO (ByteString, ByteString)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString
"", ByteString
"")
                DevServer.StatusServerStarted { IORef [ByteString]
standardOutput :: IORef [ByteString]
$sel:standardOutput:StatusServerNotStarted :: StatusServerState -> IORef [ByteString]
standardOutput, IORef [ByteString]
errorOutput :: IORef [ByteString]
$sel:errorOutput:StatusServerNotStarted :: StatusServerState -> IORef [ByteString]
errorOutput } -> do
                    ByteString
std <- ByteString -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs (ByteString -> ByteString)
-> ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [ByteString] -> ByteString
ByteString.unlines ([ByteString] -> ByteString)
-> ([ByteString] -> [ByteString]) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse ([ByteString] -> ByteString) -> IO [ByteString] -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef [ByteString] -> IO [ByteString]
forall a. IORef a -> IO a
readIORef IORef [ByteString]
standardOutput
                    ByteString
err <- ByteString -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs (ByteString -> ByteString)
-> ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [ByteString] -> ByteString
ByteString.unlines ([ByteString] -> ByteString)
-> ([ByteString] -> [ByteString]) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse ([ByteString] -> ByteString) -> IO [ByteString] -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef [ByteString] -> IO [ByteString]
forall a. IORef a -> IO a
readIORef IORef [ByteString]
errorOutput
                    (ByteString, ByteString) -> IO (ByteString, ByteString)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString
std, ByteString
err)
                DevServer.StatusServerPaused { IORef [ByteString]
$sel:standardOutput:StatusServerNotStarted :: StatusServerState -> IORef [ByteString]
standardOutput :: IORef [ByteString]
standardOutput, IORef [ByteString]
$sel:errorOutput:StatusServerNotStarted :: StatusServerState -> IORef [ByteString]
errorOutput :: IORef [ByteString]
errorOutput } -> do
                    ByteString
std <- ByteString -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs (ByteString -> ByteString)
-> ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [ByteString] -> ByteString
ByteString.unlines ([ByteString] -> ByteString)
-> ([ByteString] -> [ByteString]) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse ([ByteString] -> ByteString) -> IO [ByteString] -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef [ByteString] -> IO [ByteString]
forall a. IORef a -> IO a
readIORef IORef [ByteString]
standardOutput
                    ByteString
err <- ByteString -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs (ByteString -> ByteString)
-> ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [ByteString] -> ByteString
ByteString.unlines ([ByteString] -> ByteString)
-> ([ByteString] -> [ByteString]) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse ([ByteString] -> ByteString) -> IO [ByteString] -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef [ByteString] -> IO [ByteString]
forall a. IORef a -> IO a
readIORef IORef [ByteString]
errorOutput
                    (ByteString, ByteString) -> IO (ByteString, ByteString)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString
std, ByteString
err)

        LogsView -> IO ()
forall view.
(View view, ?context::ControllerContext) =>
view -> IO ()
render LogsView { ByteString
standardOutput :: ByteString
errorOutput :: ByteString
$sel:standardOutput:LogsView :: ByteString
$sel:errorOutput:LogsView :: ByteString
.. }

    action LogsController
PostgresLogsAction = do
        AppState
currentDevServerState <- IO AppState
(?context::ControllerContext) => IO AppState
readDevServerState
        let postgresState :: PostgresState
postgresState = AppState
currentDevServerState.postgresState

        (ByteString
standardOutput, ByteString
errorOutput) <- case PostgresState
postgresState of
                DevServer.PostgresStarted { IORef Builder
standardOutput :: IORef Builder
$sel:standardOutput:PostgresNotStarted :: PostgresState -> IORef Builder
standardOutput, IORef Builder
errorOutput :: IORef Builder
$sel:errorOutput:PostgresNotStarted :: PostgresState -> IORef Builder
errorOutput } -> do
                    ByteString
err <- ByteString -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs (ByteString -> ByteString)
-> (Builder -> ByteString) -> Builder -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Builder -> ByteString
ByteString.toLazyByteString (Builder -> ByteString) -> IO Builder -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef Builder -> IO Builder
forall a. IORef a -> IO a
readIORef IORef Builder
errorOutput
                    ByteString
std <- ByteString -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs (ByteString -> ByteString)
-> (Builder -> ByteString) -> Builder -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Builder -> ByteString
ByteString.toLazyByteString (Builder -> ByteString) -> IO Builder -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef Builder -> IO Builder
forall a. IORef a -> IO a
readIORef IORef Builder
standardOutput
                    (ByteString, ByteString) -> IO (ByteString, ByteString)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString
std, ByteString
err)
                PostgresState
_ -> (ByteString, ByteString) -> IO (ByteString, ByteString)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString
"", ByteString
"")

        LogsView -> IO ()
forall view.
(View view, ?context::ControllerContext) =>
view -> IO ()
render LogsView { ByteString
$sel:standardOutput:LogsView :: ByteString
$sel:errorOutput:LogsView :: ByteString
standardOutput :: ByteString
errorOutput :: ByteString
.. }

    action LogsController
OpenEditorAction = do
        let path :: Text
path = forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param @Text ByteString
"path"
        let line :: Int
line = forall a.
(?context::ControllerContext, ParamReader a) =>
a -> ByteString -> a
paramOrDefault @Int Int
0 ByteString
"line"
        let col :: Int
col = forall a.
(?context::ControllerContext, ParamReader a) =>
a -> ByteString -> a
paramOrDefault @Int Int
0 ByteString
"col"
        Text -> Int -> Int -> IO ()
openEditor Text
path Int
line Int
col

        (?context::ControllerContext) => ByteString -> IO ()
ByteString -> IO ()
renderPlain ByteString
""

readDevServerState :: (?context :: ControllerContext) => IO DevServer.AppState
readDevServerState :: (?context::ControllerContext) => IO AppState
readDevServerState = ((.appStateRef) (Context -> IORef AppState) -> IO Context -> IO (IORef AppState)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Context
(?context::ControllerContext) => IO Context
theDevServerContext) IO (IORef AppState)
-> (IORef AppState -> IO AppState) -> IO AppState
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IORef AppState -> IO AppState
forall a. IORef a -> IO a
readIORef