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 :: IO ()
beforeAction = (?context::ControllerContext) =>
((?context::ControllerContext) => Layout) -> IO ()
((?context::ControllerContext) => Layout) -> IO ()
setLayout (?context::ControllerContext) => Layout
Html -> Html
schemaDesignerLayout

    action :: EnumsController -> IO ()
action ShowEnumAction { Text
$sel:enumName:ShowEnumAction :: EnumsController -> Text
enumName :: 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 -> ShowEnumView
ShowEnumView { [Statement]
Text
$sel:name:ShowEnumView :: Text
$sel:statements:ShowEnumView :: [Statement]
name :: Text
statements :: [Statement]
.. }

    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] -> NewEnumView
NewEnumView { [Statement]
$sel:statements:NewEnumView :: [Statement]
statements :: [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 -> EnumsController
ShowEnumAction { Text
enumName :: Text
$sel:enumName:ShowEnumAction :: Text
.. }

    action EditEnumAction { Int
Text
$sel:enumId:ShowEnumAction :: EnumsController -> Int
enumId :: Int
enumName :: Text
$sel:enumName:ShowEnumAction :: EnumsController -> Text
.. } = 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 :: [Statement] -> Text -> Int -> EditEnumView
EditEnumView { Int
[Statement]
Text
$sel:enumId:EditEnumView :: Int
$sel:enumName:EditEnumView :: Text
$sel:statements:EditEnumView :: [Statement]
enumId :: Int
statements :: [Statement]
enumName :: Text
.. }

    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 = Proxy "name" -> Statement -> Text
forall model (name :: Symbol) value.
(KnownSymbol name, HasField name model value) =>
Proxy name -> model -> value
get IsLabel "name" (Proxy "name")
Proxy "name"
#name ([Statement]
statements [Statement] -> Int -> Statement
forall a. [a] -> Int -> a
!! Int
enumId)
        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 :: Text -> EnumsController
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 -> EnumsController
ShowEnumAction { Text
enumName :: Text
$sel:enumName:ShowEnumAction :: Text
.. }

    action DeleteEnumAction { Int
$sel:tableId:ShowEnumAction :: EnumsController -> Int
tableId :: 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 :: Text -> [Text] -> Statement
CreateEnumType { $sel:name:StatementCreateTable :: Text
name = Text
enumName, $sel:values:StatementCreateTable :: [Text]
values = (Proxy "values" -> Statement -> [Text]
forall model (name :: Symbol) value.
(KnownSymbol name, HasField name model value) =>
Proxy name -> model -> value
get IsLabel "values" (Proxy "values")
Proxy "values"
#values ([Statement]
list [Statement] -> Int -> Statement
forall a. [a] -> Int -> a
!! Int
enumId))} [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. [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)