module Sqel.Migration.Data.Ddl where

import Exon (exon)
import Generics.SOP (All, Compose, NP)
import Prelude hiding (Compose)

import Sqel.Data.Mods (Mods)
import Sqel.Data.PgType (ColumnType)
import Sqel.Data.PgTypeName (PgTypeName)
import Sqel.SOP.Constraint (symbolString)

data DdlColumnK =
  DdlColumnK {
    DdlColumnK -> Symbol
name :: Symbol,
    DdlColumnK -> Maybe Symbol
compName :: Maybe Symbol,
    DdlColumnK -> [*]
params :: [Type],
    DdlColumnK -> Maybe Symbol
rename :: Maybe Symbol,
    DdlColumnK -> Maybe Symbol
renameType :: Maybe Symbol,
    DdlColumnK -> Bool
delete :: Bool,
    DdlColumnK -> *
tpe :: Type
  }

type DdlColumn :: DdlColumnK -> Type
data DdlColumn k where
  DdlColumn ::
    KnownSymbol name =>
    Proxy name ->
    ColumnType ->
    Mods p ->
    DdlColumn ('DdlColumnK name comp p rename renameType delete a)

instance (
    Show (Mods p)
  ) => Show (DdlColumn ('DdlColumnK name comp p rename renameType delete a)) where
  showsPrec :: Int
-> DdlColumn ('DdlColumnK name comp p rename renameType delete a)
-> ShowS
showsPrec Int
d (DdlColumn Proxy name
Proxy ColumnType
ctype Mods p
p) =
    Bool -> ShowS -> ShowS
showParen (Int
d forall a. Ord a => a -> a -> Bool
> Int
10) [exon|DdlColumn #{showsPrec 11 (symbolString @name)} #{showsPrec 11 ctype} #{showsPrec 11 p}|]

data DdlTypeK =
  DdlTypeK {
    DdlTypeK -> Bool
table :: Bool,
    DdlTypeK -> Symbol
tname :: Symbol,
    DdlTypeK -> Maybe Symbol
rename :: Maybe Symbol,
    DdlTypeK -> [DdlColumnK]
columns :: [DdlColumnK]
  }

type DdlType :: DdlTypeK -> Type
data DdlType s where
  DdlType :: KnownSymbol tname => PgTypeName table -> NP DdlColumn cols -> DdlType ('DdlTypeK table tname rename cols)

instance (
    All (Compose Show DdlColumn) cols
  ) => Show (DdlType ('DdlTypeK pgName tname rename cols)) where
  showsPrec :: Int -> DdlType ('DdlTypeK pgName tname rename cols) -> ShowS
showsPrec Int
d (DdlType PgTypeName table
name NP DdlColumn cols
cols) =
    Bool -> ShowS -> ShowS
showParen (Int
d forall a. Ord a => a -> a -> Bool
> Int
10) [exon|DdlType #{showsPrec 11 name} #{showsPrec 11 cols}|]