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

// Package errors implements functions to manipulate errors.
package errors

import (
	"fmt"
	"sort"
	"strings"
)

// TODO: This package currently only provides functionality for constructing
// non-fatal errors. However, it does not currently provide functionality
// to test for a specific kind of non-fatal error, which is necessary
// for the end user.
//
// When that functionality is added, we need to think carefully about whether
// a user only cares that some kind of non-fatal error was present or whether
// all of the errors are of the same kind of non-fatal error.

// NonFatalErrors is a list of non-fatal errors where each error
// must either be a RequiredNotSet error or InvalidUTF8 error.
// The list must not be empty.
type NonFatalErrors []error

func (es NonFatalErrors) Error() string {
	ms := map[string]struct{}{}
	for _, e := range es {
		ms[e.Error()] = struct{}{}
	}
	var ss []string
	for s := range ms {
		ss = append(ss, s)
	}
	sort.Strings(ss)
	return "proto: " + strings.Join(ss, "; ")
}

// NonFatal contains non-fatal errors, which are errors that permit execution
// to continue, but should return with a non-nil error. As such, NonFatal is
// a data structure useful for swallowing non-fatal errors, but being able to
// reproduce them at the end of the function.
// An error is non-fatal if it is collection of non-fatal errors, or is
// an individual error where IsRequiredNotSet or IsInvalidUTF8 reports true.
//
// Typical usage pattern:
//	var nerr errors.NonFatal
//	...
//	if err := MyFunction(); !nerr.Merge(err) {
//		return nil, err // immediately return if err is fatal
//	}
//	...
//	return out, nerr.E
type NonFatal struct{ E error }

// Merge merges err into nf and reports whether it was successful.
// Otherwise it returns false for any fatal non-nil errors.
func (nf *NonFatal) Merge(err error) (ok bool) {
	if err == nil {
		return true // not an error
	}
	if es, ok := err.(NonFatalErrors); ok {
		nf.append(es...)
		return true // merged a list of non-fatal errors
	}
	if e, ok := err.(interface{ RequiredNotSet() bool }); ok && e.RequiredNotSet() {
		nf.append(err)
		return true // non-fatal RequiredNotSet error
	}
	if e, ok := err.(interface{ InvalidUTF8() bool }); ok && e.InvalidUTF8() {
		nf.append(err)
		return true // non-fatal InvalidUTF8 error
	}
	return false // fatal error
}

// AppendRequiredNotSet appends a RequiredNotSet error.
func (nf *NonFatal) AppendRequiredNotSet(field string) {
	nf.append(requiredNotSetError(field))
}

// AppendInvalidUTF8 appends an InvalidUTF8 error.
func (nf *NonFatal) AppendInvalidUTF8(field string) {
	nf.append(invalidUTF8Error(field))
}

func (nf *NonFatal) append(errs ...error) {
	es, _ := nf.E.(NonFatalErrors)
	es = append(es, errs...)
	nf.E = es
}

type requiredNotSetError string

func (e requiredNotSetError) Error() string {
	if e == "" {
		return "required field not set"
	}
	return string("required field " + e + " not set")
}
func (requiredNotSetError) RequiredNotSet() bool { return true }

type invalidUTF8Error string

func (e invalidUTF8Error) Error() string {
	if e == "" {
		return "invalid UTF-8 detected"
	}
	return string("field " + e + " contains invalid UTF-8")
}
func (invalidUTF8Error) InvalidUTF8() bool { return true }

// New formats a string according to the format specifier and arguments and
// returns an error that has a "proto" prefix.
func New(f string, x ...interface{}) error {
	for i := 0; i < len(x); i++ {
		if e, ok := x[i].(prefixError); ok {
			x[i] = e.s // avoid "proto: " prefix when chaining
		}
	}
	return &prefixError{s: fmt.Sprintf(f, x...)}
}

type prefixError struct{ s string }

func (e *prefixError) Error() string { return "proto: " + e.s }
