//go:build !go1.20

package uri

import (
	"errors"
	"fmt"
)

var _ Error = &uriErr{}

type uriErr struct {
	err     error
	wrapped error
}

func (e uriErr) Unwrap() error {
	return e.wrapped
}

func (e *uriErr) Is(target error) bool {
	return e == target || errors.Is(e.err, target) || errors.Is(e.wrapped, target)
}

func (e uriErr) Error() string {
	if e.wrapped != nil {
		return fmt.Sprintf("%v: %v", e.err, e.wrapped)
	}

	if e.err != nil {
		return e.err.Error()
	}

	return ""
}

// newErr emulates a wrappable error available with go1.20 standard library.
func newErr(msg string) error {
	return &uriErr{
		err: fmt.Errorf(msg),
	}
}

// errorsJoin emulates the error wrapping carried out with go1.20 errors standard library.
func errorsJoin(errs ...error) error {
	if len(errs) == 0 {
		return nil
	}

	wrappedErr := &uriErr{err: errs[0]}
	current := wrappedErr

	for _, err := range errs[1:] {
		if err == nil {
			continue
		}

		w := &uriErr{err: err}
		current.wrapped = w
		current = w
	}

	return wrappedErr
}
