// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build fuchsia

package fidl

import (
	"reflect"
	"strconv"
)

// ValidationError represents an error produced in validating a FIDL structure.
type ValidationError interface {
	error

	// Code returns the underlying ErrorCode value, which all ValidationErrors
	// must have.
	Code() ErrorCode
}

// Assert that valueError and expectError both implement the ValidationError
// interface.
var _ = []ValidationError{
	valueError{},
	expectError{},
}

// ErrorCode represents a set of machine-readable error codes each ValidationError
// has.
type ErrorCode uint32

const (
	Invalid ErrorCode = iota
	ErrUnknownOrdinal
	ErrInvalidInlineType
	ErrInvalidPointerType
	ErrVectorTooLong
	ErrStringTooLong
	ErrEnvelopeTooLong
	ErrUnexpectedOrdinal
	ErrUnexpectedNullHandle
	ErrUnexpectedNullRef
	ErrInvalidBoolValue
	ErrNotEnoughHandles
	ErrTooManyHandles
	ErrBadHandleEncoding
	ErrNonZeroPadding
	ErrBadRefEncoding
	ErrMessageTooSmall
	ErrStructIsNotPayload
	ErrInvalidUnionTag
	ErrInvalidXUnionTag
	ErrPayloadTooSmall
	ErrInvalidEmptyStruct
	ErrUnexpectedNumBytes
	ErrUnexpectedNumHandles
	ErrStringNotUTF8
)

var errorCodeNames = []string{
	Invalid:                 "Invalid",
	ErrUnknownOrdinal:       "ErrUnknownOrdinal",
	ErrInvalidInlineType:    "ErrInvalidInlineType",
	ErrInvalidPointerType:   "ErrInvalidPointerType",
	ErrVectorTooLong:        "ErrVectorTooLong",
	ErrStringTooLong:        "ErrStringTooLong",
	ErrEnvelopeTooLong:      "ErrEnvelopeTooLong",
	ErrUnexpectedOrdinal:    "ErrUnexpectedOrdinal",
	ErrUnexpectedNullHandle: "ErrUnexpectedNullHandle",
	ErrUnexpectedNullRef:    "ErrUnexpectedNullRef",
	ErrInvalidBoolValue:     "ErrInvalidBoolValue",
	ErrNotEnoughHandles:     "ErrNotEnoughHandles",
	ErrTooManyHandles:       "ErrTooManyHandles",
	ErrNonZeroPadding:       "ErrNonZeroPadding",
	ErrBadHandleEncoding:    "ErrBadHandleEncoding",
	ErrBadRefEncoding:       "ErrBadRefEncoding",
	ErrMessageTooSmall:      "ErrMessageTooSmall",
	ErrStructIsNotPayload:   "ErrStructIsNotPayload",
	ErrInvalidUnionTag:      "ErrInvalidUnionTag",
	ErrInvalidXUnionTag:     "ErrInvalidXUnionTag",
	ErrPayloadTooSmall:      "ErrPayloadTooSmall",
	ErrInvalidEmptyStruct:   "ErrInvalidEmptyStruct",
	ErrUnexpectedNumBytes:   "ErrUnexpectedNumBytes",
	ErrUnexpectedNumHandles: "ErrUnexpectedNumHandles",
	ErrStringNotUTF8:        "ErrStringNotUTF8",
}

func (c ErrorCode) String() string {
	if len(errorCodeNames) < int(c) {
		return strconv.Itoa(int(c))
	}
	return errorCodeNames[int(c)]
}

// Error implements error for ErrorCode
func (e ErrorCode) Error() string {
	switch e {
	case ErrUnknownOrdinal:
		return "unknown ordinal"
	case ErrInvalidInlineType:
		return "invalid inline type"
	case ErrInvalidPointerType:
		return "invalid pointer type"
	case ErrVectorTooLong:
		return "vector exceeds maximum size"
	case ErrStringTooLong:
		return "string exceeds maximum size"
	case ErrEnvelopeTooLong:
		return "envelope exceeds maximum size"
	case ErrUnexpectedOrdinal:
		return "unexpected ordinal"
	case ErrUnexpectedNullHandle:
		return "unexpected null handle"
	case ErrUnexpectedNullRef:
		return "unexpected null reference"
	case ErrInvalidBoolValue:
		return "unexpected boolean value"
	case ErrNotEnoughHandles:
		return "not enough handles"
	case ErrTooManyHandles:
		return "too many handles"
	case ErrBadHandleEncoding:
		return "bad encoding for handle"
	case ErrNonZeroPadding:
		return "invalid non-zero padding"
	case ErrBadRefEncoding:
		return "bad encoding for ref"
	case ErrMessageTooSmall:
		return "message too small to have FIDL header"
	case ErrStructIsNotPayload:
		return "golang struct type must implement Payload"
	case ErrInvalidUnionTag:
		return "union tag out of bounds"
	case ErrInvalidXUnionTag:
		return "strict xunion has unknown tag"
	case ErrPayloadTooSmall:
		return "payload too small"
	case ErrInvalidEmptyStruct:
		return "invalid empty struct"
	case ErrUnexpectedNumBytes:
		return "unexpected num bytes"
	case ErrUnexpectedNumHandles:
		return "unexpected num handles"
	case ErrStringNotUTF8:
		return "string is not valid UTF8"
	default:
		return e.String()
	}
}

// Code implements the ValidationError interface.
func (e ErrorCode) Code() ErrorCode {
	return e
}

// stringer is an interface for types for which a string representation
// may be derived.
type stringer interface {
	String() string
}

// toString generates the string representation for a limited set of types.
func toString(value interface{}) string {
	if e, ok := value.(error); ok {
		return e.Error()
	}
	if s, ok := value.(stringer); ok {
		return s.String()
	}
	if numbers, ok := value.([]uint64); ok {
		s := "["
		for _, num := range numbers {
			s += strconv.FormatUint(num, 10)
			s += " "
		}
		s += "]"
		return s
	}
	t := reflect.TypeOf(value)
	switch t.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return strconv.FormatInt(reflect.ValueOf(value).Int(), 10)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return strconv.FormatUint(reflect.ValueOf(value).Uint(), 10)
	case reflect.String:
		return value.(string)
	default:
		return "##BADVALUE##"
	}
}

// valueError represents an error that refers to a single value.
type valueError struct {
	ErrorCode
	value interface{}
}

func newValueError(code ErrorCode, value interface{}) valueError {
	return valueError{
		ErrorCode: code,
		value:     value,
	}
}

func (e valueError) Error() string {
	return e.ErrorCode.Error() + ": " + toString(e.value)
}

// expectError represents an error that refers to the expectation of a
// certain value, and displays a comparison between the actual value and
// the expected value.
type expectError struct {
	ErrorCode
	expect interface{}
	actual interface{}
}

func newExpectError(code ErrorCode, expect, actual interface{}) expectError {
	return expectError{
		ErrorCode: code,
		expect:    expect,
		actual:    actual,
	}
}

func (e expectError) Error() string {
	return e.ErrorCode.Error() + ": expected " + toString(e.expect) + ", got " + toString(e.actual)
}
