{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Main (main) where

-------------------------------------------------------------------------------
import Blaze.ByteString.Builder
import Control.DeepSeq
import Criterion.Main
import Data.String
import qualified Network.URI as NU
-------------------------------------------------------------------------------
import URI.ByteString

-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
instance NFData Authority

instance NFData Host

instance NFData UserInfo

instance NFData SchemaError

instance NFData URIParseError

instance NFData Scheme

instance NFData Port

instance NFData Query

instance NFData (URIRef a) where
  rnf (URI a b c d e) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d `seq` rnf e
  rnf (RelativeRef b c d e) = rnf b `seq` rnf c `seq` rnf d `seq` rnf e

-------------------------------------------------------------------------------
main :: IO ()
main =
  defaultMain
    [ bgroup
        "parsing"
        [ bench "Network.URI.parseURI" $ nf NU.parseURI exampleURIS,
          bench "URI.ByteString.parseURI strict" $ nf (parseURI strictURIParserOptions) exampleURIS,
          bench "URI.ByteString.parseURI lax" $ nf (parseURI laxURIParserOptions) exampleURIS,
          bench "URI.ByteString.parseRelativeRef strict" $ nf (parseRelativeRef strictURIParserOptions) exampleRelativeRefS,
          bench "URI.ByteString.parseRelativeRef lax" $ nf (parseRelativeRef laxURIParserOptions) exampleRelativeRefS
        ],
      bgroup
        "serializing"
        [ bench "URI.ByteString.serializeURIRef on URI" $ nf (toLazyByteString . serializeURIRef) exampleURI,
          bench "URI.ByteString.serializeURIRef on relative ref" $ nf (toLazyByteString . serializeURIRef) exampleRelativeRef
        ]
    ]

exampleURIS :: IsString s => s
exampleURIS = "http://google.com/example?params=youbetcha"

exampleRelativeRefS :: IsString s => s
exampleRelativeRefS = "/example?params=youbetcha#17u"

exampleURI :: URI
exampleURI =
  URI
    { uriScheme = Scheme "http",
      uriAuthority =
        Just
          Authority
            { authorityUserInfo = Nothing,
              authorityHost = Host "google.com",
              authorityPort = Nothing
            },
      uriPath = "/example",
      uriQuery = Query [("params", "youbetcha")],
      uriFragment = Nothing
    }

exampleRelativeRef :: RelativeRef
exampleRelativeRef =
  RelativeRef
    { rrAuthority =
        Just
          Authority
            { authorityUserInfo = Nothing,
              authorityHost = Host "google.com",
              authorityPort = Nothing
            },
      rrPath = "/example",
      rrQuery = Query [("params", "youbetcha")],
      rrFragment = Nothing
    }
