{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
--   http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--

module Thrift
    ( module Thrift.Transport
    , module Thrift.Protocol
    , AppExnType(..)
    , AppExn(..)
    , readAppExn
    , writeAppExn
    , ThriftException(..)
    ) where

import Control.Monad ( when )
import Control.Exception

import Data.Typeable ( Typeable )

import Thrift.Transport
import Thrift.Protocol


data ThriftException = ThriftException
  deriving ( Show, Typeable )
instance Exception ThriftException

data AppExnType
    = AE_UNKNOWN
    | AE_UNKNOWN_METHOD
    | AE_INVALID_MESSAGE_TYPE
    | AE_WRONG_METHOD_NAME
    | AE_BAD_SEQUENCE_ID
    | AE_MISSING_RESULT
      deriving ( Eq, Show, Typeable )

instance Enum AppExnType where
    toEnum 0 = AE_UNKNOWN
    toEnum 1 = AE_UNKNOWN_METHOD
    toEnum 2 = AE_INVALID_MESSAGE_TYPE
    toEnum 3 = AE_WRONG_METHOD_NAME
    toEnum 4 = AE_BAD_SEQUENCE_ID
    toEnum 5 = AE_MISSING_RESULT
    toEnum t = error $ "Invalid AppExnType " ++ show t

    fromEnum AE_UNKNOWN = 0
    fromEnum AE_UNKNOWN_METHOD = 1
    fromEnum AE_INVALID_MESSAGE_TYPE = 2
    fromEnum AE_WRONG_METHOD_NAME = 3
    fromEnum AE_BAD_SEQUENCE_ID = 4
    fromEnum AE_MISSING_RESULT = 5

data AppExn = AppExn { ae_type :: AppExnType, ae_message :: String }
  deriving ( Show, Typeable )
instance Exception AppExn

writeAppExn :: (Protocol p, Transport t) => p t -> AppExn -> IO ()
writeAppExn pt ae = do
    writeStructBegin pt "TApplicationException"

    when (ae_message ae /= "") $ do
        writeFieldBegin pt ("message", T_STRING , 1)
        writeString pt (ae_message ae)
        writeFieldEnd pt

    writeFieldBegin pt ("type", T_I32, 2);
    writeI32 pt (fromIntegral $ fromEnum (ae_type ae))
    writeFieldEnd pt
    writeFieldStop pt
    writeStructEnd pt

readAppExn :: (Protocol p, Transport t) => p t -> IO AppExn
readAppExn pt = do
    _ <- readStructBegin pt
    record <- readAppExnFields pt (AppExn {ae_type = undefined, ae_message = undefined})
    readStructEnd pt
    return record

readAppExnFields :: forall (a :: * -> *) t. (Protocol a, Transport t) => a t -> AppExn -> IO AppExn 
readAppExnFields pt record = do
    (_, ft, tag) <- readFieldBegin pt
    if ft == T_STOP
        then return record
        else case tag of
                 1 -> if ft == T_STRING then
                          do s <- readString pt
                             readAppExnFields pt record{ae_message = s}
                          else do skip pt ft
                                  readAppExnFields pt record
                 2 -> if ft == T_I32 then
                          do i <- readI32 pt
                             readAppExnFields pt record{ae_type = (toEnum $ fromIntegral i)}
                          else do skip pt ft
                                  readAppExnFields pt record
                 _ -> do skip pt ft
                         readFieldEnd pt
                         readAppExnFields pt record

