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

{-# LANGUAGE UndecidableInstances #-}

module Yesod.Servant.HttpApiDataInjective
  ( ToHttpApiDataInjective(..)
  ) where

import ClassyPrelude hiding (Builder)
import Web.HttpApiData
import Network.HTTP.Types.URI (encodePathSegmentsRelative)

import qualified Data.Text.Lazy as Lazy (Text)

import Data.Binary.Builder (Builder)

import Data.Void (Void)
import Data.Int (Int8, Int16)
import Data.Word (Word16)
import Numeric.Natural (Natural)
import Data.Fixed (Fixed)
import Data.UUID (UUID)
import Data.Time (ZonedTime, LocalTime, TimeOfDay, NominalDiffTime, DayOfWeek)
import Data.CaseInsensitive (CI)
import Data.CaseInsensitive.Instances ()
import qualified Data.CaseInsensitive as CI
import Data.Version (Version)
import Data.Monoid (Any, All)

import Data.CryptoID (CryptoID(..))


class ToHttpApiData a => ToHttpApiDataInjective a where
  toUrlPieceInjective :: a -> Text
  toUrlPieceInjective = toUrlPiece

  toEncodedUrlPieceInjective :: a -> Builder
  toEncodedUrlPieceInjective = encodePathSegmentsRelative . pure . toUrlPiece

  -- | Convert to HTTP header value.
  toHeaderInjective :: a -> ByteString
  toHeaderInjective = encodeUtf8 . toUrlPiece

  -- | Convert to query param value.
  toQueryParamInjective :: a -> Text
  toQueryParamInjective = toQueryParam

instance ToHttpApiDataInjective ()
instance ToHttpApiDataInjective Bool
instance ToHttpApiDataInjective Ordering
instance ToHttpApiDataInjective Void
instance ToHttpApiDataInjective Double
instance ToHttpApiDataInjective Float
instance ToHttpApiDataInjective Int
instance ToHttpApiDataInjective Int8
instance ToHttpApiDataInjective Int16
instance ToHttpApiDataInjective Int32
instance ToHttpApiDataInjective Int64
instance ToHttpApiDataInjective Integer
instance ToHttpApiDataInjective Natural
instance ToHttpApiDataInjective Word
instance ToHttpApiDataInjective Word8
instance ToHttpApiDataInjective Word16
instance ToHttpApiDataInjective Word32
instance ToHttpApiDataInjective Word64
instance ToHttpApiData (Fixed a) => ToHttpApiDataInjective (Fixed a)
instance ToHttpApiDataInjective Char
instance ToHttpApiDataInjective Text
instance ToHttpApiDataInjective Lazy.Text
instance ToHttpApiDataInjective String
instance ToHttpApiDataInjective str => ToHttpApiDataInjective (CI str) where
  toUrlPieceInjective = toUrlPieceInjective . CI.foldedCase
  toEncodedUrlPieceInjective = toEncodedUrlPieceInjective . CI.foldedCase
  toHeaderInjective = toHeaderInjective . CI.foldedCase
  toQueryParamInjective = toQueryParamInjective . CI.foldedCase
instance ToHttpApiDataInjective Version
instance ToHttpApiDataInjective All
instance ToHttpApiDataInjective Any
instance ToHttpApiDataInjective UTCTime
instance ToHttpApiDataInjective ZonedTime
instance ToHttpApiDataInjective LocalTime
instance ToHttpApiDataInjective TimeOfDay
instance ToHttpApiDataInjective NominalDiffTime
instance ToHttpApiDataInjective Day
instance ToHttpApiDataInjective DayOfWeek
instance ToHttpApiDataInjective UUID
instance ToHttpApiDataInjective a => ToHttpApiDataInjective (Maybe a)
instance ToHttpApiDataInjective a => ToHttpApiDataInjective (CryptoID ns a) where
  toUrlPieceInjective = toUrlPieceInjective . ciphertext
  toEncodedUrlPieceInjective = toEncodedUrlPieceInjective . ciphertext
  toHeaderInjective = toHeaderInjective . ciphertext
  toQueryParamInjective = toQueryParamInjective . ciphertext
