/*
 * 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.
 */

package thrift

import (
	"context"
)

const (
	UNKNOWN_APPLICATION_EXCEPTION  = 0
	UNKNOWN_METHOD                 = 1
	INVALID_MESSAGE_TYPE_EXCEPTION = 2
	WRONG_METHOD_NAME              = 3
	BAD_SEQUENCE_ID                = 4
	MISSING_RESULT                 = 5
	INTERNAL_ERROR                 = 6
	PROTOCOL_ERROR                 = 7
	INVALID_TRANSFORM              = 8
	INVALID_PROTOCOL               = 9
	UNSUPPORTED_CLIENT_TYPE        = 10
)

var defaultApplicationExceptionMessage = map[int32]string{
	UNKNOWN_APPLICATION_EXCEPTION:  "unknown application exception",
	UNKNOWN_METHOD:                 "unknown method",
	INVALID_MESSAGE_TYPE_EXCEPTION: "invalid message type",
	WRONG_METHOD_NAME:              "wrong method name",
	BAD_SEQUENCE_ID:                "bad sequence ID",
	MISSING_RESULT:                 "missing result",
	INTERNAL_ERROR:                 "unknown internal error",
	PROTOCOL_ERROR:                 "unknown protocol error",
	INVALID_TRANSFORM:              "Invalid transform",
	INVALID_PROTOCOL:               "Invalid protocol",
	UNSUPPORTED_CLIENT_TYPE:        "Unsupported client type",
}

// Application level Thrift exception
type TApplicationException interface {
	TException
	TypeId() int32
	Read(ctx context.Context, iprot TProtocol) error
	Write(ctx context.Context, oprot TProtocol) error
}

type tApplicationException struct {
	message string
	type_   int32
}

func (e tApplicationException) Error() string {
	if e.message != "" {
		return e.message
	}
	return defaultApplicationExceptionMessage[e.type_]
}

func NewTApplicationException(type_ int32, message string) TApplicationException {
	return &tApplicationException{message, type_}
}

func (p *tApplicationException) TypeId() int32 {
	return p.type_
}

func (p *tApplicationException) Read(ctx context.Context, iprot TProtocol) error {
	// TODO: this should really be generated by the compiler
	_, err := iprot.ReadStructBegin(ctx)
	if err != nil {
		return err
	}

	message := ""
	type_ := int32(UNKNOWN_APPLICATION_EXCEPTION)

	for {
		_, ttype, id, err := iprot.ReadFieldBegin(ctx)
		if err != nil {
			return err
		}
		if ttype == STOP {
			break
		}
		switch id {
		case 1:
			if ttype == STRING {
				if message, err = iprot.ReadString(ctx); err != nil {
					return err
				}
			} else {
				if err = SkipDefaultDepth(ctx, iprot, ttype); err != nil {
					return err
				}
			}
		case 2:
			if ttype == I32 {
				if type_, err = iprot.ReadI32(ctx); err != nil {
					return err
				}
			} else {
				if err = SkipDefaultDepth(ctx, iprot, ttype); err != nil {
					return err
				}
			}
		default:
			if err = SkipDefaultDepth(ctx, iprot, ttype); err != nil {
				return err
			}
		}
		if err = iprot.ReadFieldEnd(ctx); err != nil {
			return err
		}
	}
	if err := iprot.ReadStructEnd(ctx); err != nil {
		return err
	}

	p.message = message
	p.type_ = type_

	return nil
}

func (p *tApplicationException) Write(ctx context.Context, oprot TProtocol) (err error) {
	err = oprot.WriteStructBegin(ctx, "TApplicationException")
	if len(p.Error()) > 0 {
		err = oprot.WriteFieldBegin(ctx, "message", STRING, 1)
		if err != nil {
			return
		}
		err = oprot.WriteString(ctx, p.Error())
		if err != nil {
			return
		}
		err = oprot.WriteFieldEnd(ctx)
		if err != nil {
			return
		}
	}
	err = oprot.WriteFieldBegin(ctx, "type", I32, 2)
	if err != nil {
		return
	}
	err = oprot.WriteI32(ctx, p.type_)
	if err != nil {
		return
	}
	err = oprot.WriteFieldEnd(ctx)
	if err != nil {
		return
	}
	err = oprot.WriteFieldStop(ctx)
	if err != nil {
		return
	}
	err = oprot.WriteStructEnd(ctx)
	return
}
