module IHP.IDE.SchemaDesigner.Controller.Enums where

import IHP.ControllerPrelude
import IHP.IDE.ToolServer.Types

import IHP.IDE.SchemaDesigner.View.Enums.New
import IHP.IDE.SchemaDesigner.View.Enums.Show
import IHP.IDE.SchemaDesigner.View.Enums.Edit

import IHP.IDE.SchemaDesigner.Types
import IHP.IDE.SchemaDesigner.View.Layout (replace, schemaDesignerLayout)
import IHP.IDE.SchemaDesigner.Controller.Helper
import IHP.IDE.SchemaDesigner.Controller.Validation

import qualified IHP.IDE.SchemaDesigner.SchemaOperations as SchemaOperations

instance Controller EnumsController where
    beforeAction :: (?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::EnumsController) =>
IO ()
beforeAction = (?context::ControllerContext) =>
((?context::ControllerContext) => Layout) -> IO ()
((?context::ControllerContext) => Layout) -> IO ()
setLayout (?context::ControllerContext) => Layout
Layout
Html -> Html
schemaDesignerLayout

    action :: (?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::EnumsController) =>
EnumsController -> IO ()
action ShowEnumAction { Text
enumName :: Text
$sel:enumName:ShowEnumAction :: EnumsController -> Text
.. } = do
        [Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::controller) =>
IO [Statement]
readSchema
        let name :: Text
name = Text
enumName
        ShowEnumView -> IO ()
forall view.
(View view, ?context::ControllerContext) =>
view -> IO ()
render ShowEnumView { [Statement]
Text
statements :: [Statement]
name :: Text
$sel:statements:ShowEnumView :: [Statement]
$sel:name:ShowEnumView :: Text
.. }

    action EnumsController
NewEnumAction = do
        [Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::controller) =>
IO [Statement]
readSchema
        NewEnumView -> IO ()
forall view.
(View view, ?context::ControllerContext) =>
view -> IO ()
render NewEnumView { [Statement]
statements :: [Statement]
$sel:statements:NewEnumView :: [Statement]
.. }

    action EnumsController
CreateEnumAction = do
        [Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::controller) =>
IO [Statement]
readSchema
        let enumName :: Text
enumName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"enumName"
        let validationResult :: ValidatorResult
validationResult = Text
enumName Text -> (Text -> ValidatorResult) -> ValidatorResult
forall {t1} {t2}. t1 -> (t1 -> t2) -> t2
|> [Statement] -> Maybe Text -> Text -> ValidatorResult
validateEnum [Statement]
statements Maybe Text
forall a. Maybe a
Nothing
        case ValidatorResult
validationResult of
            Failure Text
message -> do
                (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
setErrorMessage Text
message
                TablesController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo TablesController
TablesAction
            ValidatorResult
Success -> do
                ([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema (([Statement] -> [Statement]) -> IO ())
-> ([Statement] -> [Statement]) -> IO ()
forall a b. (a -> b) -> a -> b
$ Text -> [Statement] -> [Statement]
SchemaOperations.addEnum Text
enumName
                EnumsController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowEnumAction { Text
$sel:enumName:ShowEnumAction :: Text
enumName :: Text
.. }

    action EditEnumAction { Int
Text
$sel:enumName:ShowEnumAction :: EnumsController -> Text
enumName :: Text
enumId :: Int
$sel:enumId:ShowEnumAction :: EnumsController -> Int
.. } = do
        [Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::controller) =>
IO [Statement]
readSchema
        let enumId :: Int
enumId = ByteString -> Int
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"enumId"
        EditEnumView -> IO ()
forall view.
(View view, ?context::ControllerContext) =>
view -> IO ()
render EditEnumView { Int
[Statement]
Text
enumName :: Text
statements :: [Statement]
enumId :: Int
$sel:statements:EditEnumView :: [Statement]
$sel:enumName:EditEnumView :: Text
$sel:enumId:EditEnumView :: Int
.. }

    action EnumsController
UpdateEnumAction = do
        [Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::controller) =>
IO [Statement]
readSchema
        let enumName :: Text
enumName = ByteString -> Text
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"enumName"
        let enumId :: Int
enumId = ByteString -> Int
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"enumId"
        let oldEnumName :: Text
oldEnumName = ([Statement]
statements [Statement] -> Int -> Statement
forall a. HasCallStack => [a] -> Int -> a
!! Int
enumId).name
        let validationResult :: ValidatorResult
validationResult = Text
enumName Text -> (Text -> ValidatorResult) -> ValidatorResult
forall {t1} {t2}. t1 -> (t1 -> t2) -> t2
|> [Statement] -> Maybe Text -> Text -> ValidatorResult
validateEnum [Statement]
statements (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
oldEnumName)
        case ValidatorResult
validationResult of
            Failure Text
message -> do
                (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
setErrorMessage Text
message
                EnumsController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowEnumAction { $sel:enumName:ShowEnumAction :: Text
enumName = Text
oldEnumName }
            ValidatorResult
Success -> do
                ([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema (Int -> Text -> [Statement] -> [Statement]
updateEnum Int
enumId Text
enumName)
                EnumsController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo ShowEnumAction { Text
$sel:enumName:ShowEnumAction :: Text
enumName :: Text
.. }

    action DeleteEnumAction { Int
tableId :: Int
$sel:tableId:ShowEnumAction :: EnumsController -> Int
.. } = do
        let tableId :: Int
tableId = ByteString -> Int
forall valueType.
(?context::ControllerContext, ParamReader valueType) =>
ByteString -> valueType
param ByteString
"tableId"
        ([Statement] -> [Statement]) -> IO ()
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::controller) =>
([Statement] -> [Statement]) -> IO ()
updateSchema (Int -> [Statement] -> [Statement]
deleteEnum Int
tableId)
        TablesController -> IO ()
forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo TablesController
TablesAction

updateEnum :: Int -> Text -> [Statement] -> [Statement]
updateEnum :: Int -> Text -> [Statement] -> [Statement]
updateEnum Int
enumId Text
enumName [Statement]
list = Int -> Statement -> [Statement] -> [Statement]
forall a. Int -> a -> [a] -> [a]
replace Int
enumId CreateEnumType { $sel:name:StatementCreateTable :: Text
name = Text
enumName, $sel:values:StatementCreateTable :: [Text]
values = ([Statement]
list [Statement] -> Int -> Statement
forall a. HasCallStack => [a] -> Int -> a
!! Int
enumId).values } [Statement]
list

deleteEnum :: Int -> [Statement] -> [Statement]
deleteEnum :: Int -> [Statement] -> [Statement]
deleteEnum Int
tableId [Statement]
list = Statement -> [Statement] -> [Statement]
forall a. Eq a => a -> [a] -> [a]
delete ([Statement]
list [Statement] -> Int -> Statement
forall a. HasCallStack => [a] -> Int -> a
!! Int
tableId) [Statement]
list

validateEnum :: [Statement] -> Maybe Text -> Validator Text
validateEnum :: [Statement] -> Maybe Text -> Text -> ValidatorResult
validateEnum [Statement]
statements = Text -> [Text] -> Maybe Text -> Text -> ValidatorResult
validateNameInSchema Text
"enum name" ([Statement] -> [Text]
getAllObjectNames [Statement]
statements)