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

import (
	"fmt"
	"strings"
	"unicode"
	"unicode/utf8"

	"golang.org/x/xerrors/internal"
)

const percentBangString = "%!"

// Errorf formats according to a format specifier and returns the string as a
// value that satisfies error.
//
// The returned error includes the file and line number of the caller when
// formatted with additional detail enabled. If the last argument is an error
// the returned error's Format method will return it if the format string ends
// with ": %s", ": %v", or ": %w". If the last argument is an error and the
// format string ends with ": %w", the returned error implements an Unwrap
// method returning it.
//
// If the format specifier includes a %w verb with an error operand in a
// position other than at the end, the returned error will still implement an
// Unwrap method returning the operand, but the error's Format method will not
// return the wrapped error.
//
// It is invalid to include more than one %w verb or to supply it with an
// operand that does not implement the error interface. The %w verb is otherwise
// a synonym for %v.
//
// Deprecated: As of Go 1.13, use fmt.Errorf instead.
func Errorf(format string, a ...interface{}) error {
	format = formatPlusW(format)
	// Support a ": %[wsv]" suffix, which works well with xerrors.Formatter.
	wrap := strings.HasSuffix(format, ": %w")
	idx, format2, ok := parsePercentW(format)
	percentWElsewhere := !wrap && idx >= 0
	if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) {
		err := errorAt(a, len(a)-1)
		if err == nil {
			return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)}
		}
		// TODO: this is not entirely correct. The error value could be
		// printed elsewhere in format if it mixes numbered with unnumbered
		// substitutions. With relatively small changes to doPrintf we can
		// have it optionally ignore extra arguments and pass the argument
		// list in its entirety.
		msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...)
		frame := Frame{}
		if internal.EnableTrace {
			frame = Caller(1)
		}
		if wrap {
			return &wrapError{msg, err, frame}
		}
		return &noWrapError{msg, err, frame}
	}
	// Support %w anywhere.
	// TODO: don't repeat the wrapped error's message when %w occurs in the middle.
	msg := fmt.Sprintf(format2, a...)
	if idx < 0 {
		return &noWrapError{msg, nil, Caller(1)}
	}
	err := errorAt(a, idx)
	if !ok || err == nil {
		// Too many %ws or argument of %w is not an error. Approximate the Go
		// 1.13 fmt.Errorf message.
		return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)}
	}
	frame := Frame{}
	if internal.EnableTrace {
		frame = Caller(1)
	}
	return &wrapError{msg, err, frame}
}

func errorAt(args []interface{}, i int) error {
	if i < 0 || i >= len(args) {
		return nil
	}
	err, ok := args[i].(error)
	if !ok {
		return nil
	}
	return err
}

// formatPlusW is used to avoid the vet check that will barf at %w.
func formatPlusW(s string) string {
	return s
}

// Return the index of the only %w in format, or -1 if none.
// Also return a rewritten format string with %w replaced by %v, and
// false if there is more than one %w.
// TODO: handle "%[N]w".
func parsePercentW(format string) (idx int, newFormat string, ok bool) {
	// Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go.
	idx = -1
	ok = true
	n := 0
	sz := 0
	var isW bool
	for i := 0; i < len(format); i += sz {
		if format[i] != '%' {
			sz = 1
			continue
		}
		// "%%" is not a format directive.
		if i+1 < len(format) && format[i+1] == '%' {
			sz = 2
			continue
		}
		sz, isW = parsePrintfVerb(format[i:])
		if isW {
			if idx >= 0 {
				ok = false
			} else {
				idx = n
			}
			// "Replace" the last character, the 'w', with a 'v'.
			p := i + sz - 1
			format = format[:p] + "v" + format[p+1:]
		}
		n++
	}
	return idx, format, ok
}

// Parse the printf verb starting with a % at s[0].
// Return how many bytes it occupies and whether the verb is 'w'.
func parsePrintfVerb(s string) (int, bool) {
	// Assume only that the directive is a sequence of non-letters followed by a single letter.
	sz := 0
	var r rune
	for i := 1; i < len(s); i += sz {
		r, sz = utf8.DecodeRuneInString(s[i:])
		if unicode.IsLetter(r) {
			return i + sz, r == 'w'
		}
	}
	return len(s), false
}

type noWrapError struct {
	msg   string
	err   error
	frame Frame
}

func (e *noWrapError) Error() string {
	return fmt.Sprint(e)
}

func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) }

func (e *noWrapError) FormatError(p Printer) (next error) {
	p.Print(e.msg)
	e.frame.Format(p)
	return e.err
}

type wrapError struct {
	msg   string
	err   error
	frame Frame
}

func (e *wrapError) Error() string {
	return fmt.Sprint(e)
}

func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) }

func (e *wrapError) FormatError(p Printer) (next error) {
	p.Print(e.msg)
	e.frame.Format(p)
	return e.err
}

func (e *wrapError) Unwrap() error {
	return e.err
}
