/*
 *
 * Copyright 2020 gRPC authors.
 *
 * Licensed 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 client

import "fmt"

// ErrorType is the type of the error that the watcher will receive from the xds
// client.
type ErrorType int

const (
	// ErrorTypeUnknown indicates the error doesn't have a specific type. It is
	// the default value, and is returned if the error is not an xds error.
	ErrorTypeUnknown ErrorType = iota
	// ErrorTypeConnection indicates a connection error from the gRPC client.
	ErrorTypeConnection
	// ErrorTypeResourceNotFound indicates a resource is not found from the xds
	// response. It's typically returned if the resource is removed in the xds
	// server.
	ErrorTypeResourceNotFound
)

type xdsClientError struct {
	t    ErrorType
	desc string
}

func (e *xdsClientError) Error() string {
	return e.desc
}

// NewErrorf creates an xds client error. The callbacks are called with this
// error, to pass additional information about the error.
func NewErrorf(t ErrorType, format string, args ...interface{}) error {
	return &xdsClientError{t: t, desc: fmt.Sprintf(format, args...)}
}

// ErrType returns the error's type.
func ErrType(e error) ErrorType {
	if xe, ok := e.(*xdsClientError); ok {
		return xe.t
	}
	return ErrorTypeUnknown
}
