-- SPDX-FileCopyrightText: 2022 Sarah Vaupel <sarah.vaupel@ifi.lmu.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later

module Model.Types.Apis
  ( ExternalApiKind(..)
  , ExternalApiConfig(..)
  , GradelistFormatIdent
  , classifyExternalApiConfig
  , module Servant.Client.Core.BaseUrl
  ) where

import Import.NoModel

import Servant.Client.Core.BaseUrl (BaseUrl(..), Scheme(..))

import Data.Aeson (genericToJSON, genericParseJSON)
import Data.Swagger (SwaggerType(..), ToParamSchema(..), enum_, type_, paramSchemaToSchema, ToSchema(..), fromAesonOptions, genericDeclareNamedSchema)
import Data.Swagger.Internal.Schema (named)

import qualified Data.HashSet as HashSet

{-# ANN module ("HLint: ignore Use newtype instead of data" :: String) #-}


data ExternalApiKind = EApiKindGradelistFormat
  deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic)
  deriving anyclass (Universe, Finite, Hashable)
nullaryPathPiece ''ExternalApiKind $ camelToPathPiece' 3
pathPieceJSON ''ExternalApiKind
instance ToParamSchema ExternalApiKind where
  toParamSchema _ = mempty
    & type_ ?~ SwaggerString
    & enum_ ?~ map toJSON (universeF @ExternalApiKind)
instance ToSchema ExternalApiKind where
  declareNamedSchema = pure . named "ExternalApiKind" . paramSchemaToSchema
instance ToSample ExternalApiKind where
  toSamples _ = samples universeF

type GradelistFormatIdent = CI Text
  
data ExternalApiConfig
  = EApiGradelistFormat
    { eapiGradelistFormats :: NonNull (HashSet GradelistFormatIdent)
    }
  deriving (Eq, Ord, Read, Show, Generic)
  deriving anyclass (NFData)
instance ToJSON ExternalApiConfig where
  toJSON = genericToJSON externalApiConfigAesonOptions
instance FromJSON ExternalApiConfig where
  parseJSON = genericParseJSON externalApiConfigAesonOptions
instance ToSchema ExternalApiConfig where
  declareNamedSchema = genericDeclareNamedSchema $ fromAesonOptions externalApiConfigAesonOptions

derivePersistFieldJSON ''ExternalApiConfig

instance ToSample ExternalApiConfig where
  toSamples _ = gradelistFormatters
    where gradelistFormatters = samples
            [ EApiGradelistFormat . impureNonNull $ HashSet.singleton "Format 1"
            , EApiGradelistFormat . impureNonNull $ HashSet.fromList ["Format 1", "Format 2"]
            ]

classifyExternalApiConfig :: ExternalApiConfig -> ExternalApiKind
classifyExternalApiConfig EApiGradelistFormat{} = EApiKindGradelistFormat
