/*
 * Copyright 2022 CloudWeGo 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 defs

import (
	"fmt"
	"reflect"
)

type TypeError struct {
	Note string
	Type reflect.Type
}

func (e TypeError) Error() string {
	return fmt.Sprintf("TypeError(%s): %s", e.Type, e.Note)
}

type SyntaxError struct {
	Pos    int
	Src    string
	Reason string
}

func (e SyntaxError) Error() string {
	return fmt.Sprintf("Syntax error at position %d: %s", e.Pos, e.Reason)
}

func EType(vt reflect.Type, note string) TypeError {
	return TypeError{
		Type: vt,
		Note: note,
	}
}

func ESyntax(pos int, src string, reason string) SyntaxError {
	return SyntaxError{
		Pos:    pos,
		Src:    src,
		Reason: reason,
	}
}

func ESetList(pos int, src string, vt reflect.Type) SyntaxError {
	return ESyntax(pos, src,
		fmt.Sprintf(`ambiguous type between set<%s> and list<%s>,`+
			` please specify in the "frugal" or "thrift" tag`, vt, vt))
}

func EUseOther(vt reflect.Type, alt string) TypeError {
	return TypeError{
		Type: vt,
		Note: fmt.Sprintf("Thrift does not support %s, use %s instead", vt, alt),
	}
}
