module IHP.IDE.SchemaDesigner.View.Schema.SchemaUpdateFailed where

import IHP.ViewPrelude
import IHP.IDE.SchemaDesigner.Types
import IHP.IDE.ToolServer.Types
import IHP.IDE.ToolServer.Layout
import IHP.IDE.SchemaDesigner.View.Layout
import System.Exit
import qualified Data.Text as Text

data SchemaUpdateFailedView = SchemaUpdateFailedView
    { SchemaUpdateFailedView -> Text
output :: Text
    , SchemaUpdateFailedView -> ExitCode
exitCode :: ExitCode
    }

instance View SchemaUpdateFailedView where
    html :: SchemaUpdateFailedView -> Html
html SchemaUpdateFailedView { Text
ExitCode
exitCode :: ExitCode
output :: Text
$sel:exitCode:SchemaUpdateFailedView :: SchemaUpdateFailedView -> ExitCode
$sel:output:SchemaUpdateFailedView :: SchemaUpdateFailedView -> Text
.. } = Modal -> Html
renderModal Modal :: Html -> Maybe Html -> Text -> Text -> Modal
Modal
                { $sel:modalTitle:Modal :: Text
modalTitle = Text
"Open your Fixtures.sql and apply required changes to fix this error. After that try again."
                , $sel:modalCloseUrl:Modal :: Text
modalCloseUrl = TablesController -> Text
forall controller. HasPath controller => controller -> Text
pathTo TablesController
TablesAction
                , $sel:modalFooter:Modal :: Maybe Html
modalFooter = Maybe Html
forall a. Maybe a
Nothing
                , $sel:modalContent:Modal :: Html
modalContent = [hsx|
                        <div class={classes ["schema-update-failed", ("sql-error", isSqlError)]}>
                            {forEach errorMessages renderError}
                            {outputLines |> map renderLine |> mconcat}
                        </div>
                    |]
                }

        where
            -- | E.g. the make db succeeded but there an sql error inside the output
            isSqlError :: Bool
isSqlError = ExitCode
exitCode ExitCode -> ExitCode -> Bool
forall a. Eq a => a -> a -> Bool
== ExitCode
ExitSuccess

            outputLines :: [Text]
            outputLines :: [Text]
outputLines = Text -> [Text]
Text.lines Text
output

            errorMessages :: [Text]
            errorMessages :: [Text]
errorMessages = 
                    [Int] -> [Text] -> [(Int, Text)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] [Text]
outputLines
                    [(Int, Text)] -> ([(Int, Text)] -> [(Int, Text)]) -> [(Int, Text)]
forall t1 t2. t1 -> (t1 -> t2) -> t2
|> ((Int, Text) -> Bool) -> [(Int, Text)] -> [(Int, Text)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(Int
i, Text
line) -> Text
"ERROR" Text -> Text -> Bool
`Text.isInfixOf` Text
line)
                    [(Int, Text)] -> ([(Int, Text)] -> [(Int, Text)]) -> [(Int, Text)]
forall t1 t2. t1 -> (t1 -> t2) -> t2
|> ((Int, Text) -> (Int, Text)) -> [(Int, Text)] -> [(Int, Text)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Int
i, Text
line) ->
                            let Text
nextLine :: Text = if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Text] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
outputLines then [Text]
outputLines [Text] -> Int -> Text
forall a. [a] -> Int -> a
!! (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) else Text
""
                            in
                                if Text
"DETAIL" Text -> Text -> Bool
`isPrefixOf` Text
nextLine
                                    then (Int
i, Text
line Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
nextLine)
                                    else (Int
i, Text
line)
                        )
                    [(Int, Text)] -> ([(Int, Text)] -> [Text]) -> [Text]
forall t1 t2. t1 -> (t1 -> t2) -> t2
|> ((Int, Text) -> Text) -> [(Int, Text)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Text) -> Text
forall a b. (a, b) -> b
snd

            renderError :: text -> Html
renderError text
message = [hsx|<div class="error">{nl2br message}</div>|]

            renderLine :: Text -> Html
            renderLine :: Text -> Html
renderLine Text
line = [hsx|<div>{line}</div>|]