module FFICXX.Generate.Type.Module where

--
import FFICXX.Generate.Type.Cabal (AddCInc, AddCSrc)
import FFICXX.Generate.Type.Class (Class, TemplateClass, TopLevel)
import FFICXX.Runtime.CodeGen.Cxx (HeaderName (..), Namespace (..))

--
-- Import/Header
--
--   HPkg is generated C++ headers by fficxx, CPkg is original C++ headers
data ClassImportHeader = ClassImportHeader
  { ClassImportHeader -> Class
cihClass :: Class,
    -- | fficxx-side main header
    ClassImportHeader -> HeaderName
cihSelfHeader :: HeaderName,
    ClassImportHeader -> [Namespace]
cihNamespace :: [Namespace],
    ClassImportHeader -> String
cihSelfCpp :: String,
    -- | Dependencies TODO: clarify this.
    ClassImportHeader -> [Either TemplateClass Class]
cihImportedClasses :: [Either TemplateClass Class],
    ClassImportHeader -> [HeaderName]
cihIncludedHPkgHeadersInH :: [HeaderName], -- TODO: Explain why we need to have these two
    ClassImportHeader -> [HeaderName]
cihIncludedHPkgHeadersInCPP :: [HeaderName], --       separately.

    -- | C++-side headers
    ClassImportHeader -> [HeaderName]
cihIncludedCPkgHeaders :: [HeaderName]
  }
  deriving (Int -> ClassImportHeader -> ShowS
[ClassImportHeader] -> ShowS
ClassImportHeader -> String
(Int -> ClassImportHeader -> ShowS)
-> (ClassImportHeader -> String)
-> ([ClassImportHeader] -> ShowS)
-> Show ClassImportHeader
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ClassImportHeader -> ShowS
showsPrec :: Int -> ClassImportHeader -> ShowS
$cshow :: ClassImportHeader -> String
show :: ClassImportHeader -> String
$cshowList :: [ClassImportHeader] -> ShowS
showList :: [ClassImportHeader] -> ShowS
Show)

--
-- Submodule
--

data ClassSubmoduleType
  = CSTRawType
  | CSTInterface
  | CSTImplementation
  | CSTFFI
  | CSTCast
  deriving (Int -> ClassSubmoduleType -> ShowS
[ClassSubmoduleType] -> ShowS
ClassSubmoduleType -> String
(Int -> ClassSubmoduleType -> ShowS)
-> (ClassSubmoduleType -> String)
-> ([ClassSubmoduleType] -> ShowS)
-> Show ClassSubmoduleType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ClassSubmoduleType -> ShowS
showsPrec :: Int -> ClassSubmoduleType -> ShowS
$cshow :: ClassSubmoduleType -> String
show :: ClassSubmoduleType -> String
$cshowList :: [ClassSubmoduleType] -> ShowS
showList :: [ClassSubmoduleType] -> ShowS
Show)

data TemplateClassSubmoduleType
  = TCSTTH
  | TCSTTemplate
  deriving (Int -> TemplateClassSubmoduleType -> ShowS
[TemplateClassSubmoduleType] -> ShowS
TemplateClassSubmoduleType -> String
(Int -> TemplateClassSubmoduleType -> ShowS)
-> (TemplateClassSubmoduleType -> String)
-> ([TemplateClassSubmoduleType] -> ShowS)
-> Show TemplateClassSubmoduleType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TemplateClassSubmoduleType -> ShowS
showsPrec :: Int -> TemplateClassSubmoduleType -> ShowS
$cshow :: TemplateClassSubmoduleType -> String
show :: TemplateClassSubmoduleType -> String
$cshowList :: [TemplateClassSubmoduleType] -> ShowS
showList :: [TemplateClassSubmoduleType] -> ShowS
Show)

-- | UClass = Unified Class, either template class or ordinary class
type UClass = Either TemplateClass Class

type UClassSubmodule =
  Either (TemplateClassSubmoduleType, TemplateClass) (ClassSubmoduleType, Class)

-- | Dependency cycle information. Currently just a string
--                  self,    former,   latter
type DepCycles = [[(String, ([String], [String]))]]

--
-- Module
--

data ClassModule = ClassModule
  { ClassModule -> String
cmModule :: String,
    ClassModule -> ClassImportHeader
cmCIH :: ClassImportHeader,
    -- | imported submodules for Interface.hs
    ClassModule -> [UClassSubmodule]
cmImportedSubmodulesForInterface :: [UClassSubmodule],
    -- | imported submodules for FFI.hs
    ClassModule -> [UClassSubmodule]
cmImportedSubmodulesForFFI :: [UClassSubmodule],
    -- | imported submodules for Cast.hs
    ClassModule -> [UClassSubmodule]
cmImportedSubmodulesForCast,
    -- imported submodules for Implementation.hs
    ClassModule -> [UClassSubmodule]
cmImportedSubmodulesForImplementation ::
      [UClassSubmodule],
    ClassModule -> [String]
cmExtraImport :: [String]
  }
  deriving (Int -> ClassModule -> ShowS
[ClassModule] -> ShowS
ClassModule -> String
(Int -> ClassModule -> ShowS)
-> (ClassModule -> String)
-> ([ClassModule] -> ShowS)
-> Show ClassModule
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ClassModule -> ShowS
showsPrec :: Int -> ClassModule -> ShowS
$cshow :: ClassModule -> String
show :: ClassModule -> String
$cshowList :: [ClassModule] -> ShowS
showList :: [ClassModule] -> ShowS
Show)

data TemplateClassModule = TCM
  { TemplateClassModule -> String
tcmModule :: String,
    TemplateClassModule -> TemplateClassImportHeader
tcmTCIH :: TemplateClassImportHeader
  }
  deriving (Int -> TemplateClassModule -> ShowS
[TemplateClassModule] -> ShowS
TemplateClassModule -> String
(Int -> TemplateClassModule -> ShowS)
-> (TemplateClassModule -> String)
-> ([TemplateClassModule] -> ShowS)
-> Show TemplateClassModule
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TemplateClassModule -> ShowS
showsPrec :: Int -> TemplateClassModule -> ShowS
$cshow :: TemplateClassModule -> String
show :: TemplateClassModule -> String
$cshowList :: [TemplateClassModule] -> ShowS
showList :: [TemplateClassModule] -> ShowS
Show)

data TemplateClassImportHeader = TCIH
  { TemplateClassImportHeader -> TemplateClass
tcihTClass :: TemplateClass,
    -- | C++-side headers
    TemplateClassImportHeader -> [HeaderName]
tcihCxxHeaders :: [HeaderName]
  }
  deriving (Int -> TemplateClassImportHeader -> ShowS
[TemplateClassImportHeader] -> ShowS
TemplateClassImportHeader -> String
(Int -> TemplateClassImportHeader -> ShowS)
-> (TemplateClassImportHeader -> String)
-> ([TemplateClassImportHeader] -> ShowS)
-> Show TemplateClassImportHeader
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TemplateClassImportHeader -> ShowS
showsPrec :: Int -> TemplateClassImportHeader -> ShowS
$cshow :: TemplateClassImportHeader -> String
show :: TemplateClassImportHeader -> String
$cshowList :: [TemplateClassImportHeader] -> ShowS
showList :: [TemplateClassImportHeader] -> ShowS
Show)

data TopLevelImportHeader = TopLevelImportHeader
  { TopLevelImportHeader -> String
tihHeaderFileName :: String,
    TopLevelImportHeader -> [ClassImportHeader]
tihClassDep :: [ClassImportHeader],
    -- | Extra class dependencies outside current package.
    --   NOTE: we cannot fully construct ClassImportHeader for them.
    TopLevelImportHeader -> [Either TemplateClass Class]
tihExtraClassDep :: [Either TemplateClass Class],
    TopLevelImportHeader -> [TopLevel]
tihFuncs :: [TopLevel],
    TopLevelImportHeader -> [Namespace]
tihNamespaces :: [Namespace],
    TopLevelImportHeader -> [HeaderName]
tihExtraHeadersInH :: [HeaderName],
    TopLevelImportHeader -> [HeaderName]
tihExtraHeadersInCPP :: [HeaderName]
  }
  deriving (Int -> TopLevelImportHeader -> ShowS
[TopLevelImportHeader] -> ShowS
TopLevelImportHeader -> String
(Int -> TopLevelImportHeader -> ShowS)
-> (TopLevelImportHeader -> String)
-> ([TopLevelImportHeader] -> ShowS)
-> Show TopLevelImportHeader
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TopLevelImportHeader -> ShowS
showsPrec :: Int -> TopLevelImportHeader -> ShowS
$cshow :: TopLevelImportHeader -> String
show :: TopLevelImportHeader -> String
$cshowList :: [TopLevelImportHeader] -> ShowS
showList :: [TopLevelImportHeader] -> ShowS
Show)

--
-- Package-level
--

data PackageConfig = PkgConfig
  { PackageConfig -> [ClassModule]
pcfg_classModules :: [ClassModule],
    PackageConfig -> [ClassImportHeader]
pcfg_classImportHeaders :: [ClassImportHeader],
    PackageConfig -> TopLevelImportHeader
pcfg_topLevelImportHeader :: TopLevelImportHeader,
    PackageConfig -> [TemplateClassModule]
pcfg_templateClassModules :: [TemplateClassModule],
    PackageConfig -> [TemplateClassImportHeader]
pcfg_templateClassImportHeaders :: [TemplateClassImportHeader],
    PackageConfig -> [AddCInc]
pcfg_additional_c_incs :: [AddCInc],
    PackageConfig -> [AddCSrc]
pcfg_additional_c_srcs :: [AddCSrc]
  }