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

var _ TApplicationException = (*tApplicationException)(nil)

func (tApplicationException) TExceptionType() TExceptionType {
	return TExceptionTypeApplication
}

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
}
