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

import (
	"bytes"
	"strings"

	"golang.org/x/exp/errors"
	"golang.org/x/exp/errors/internal"
)

// 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 errors.Wrapper
// with an Unwrap method returning it.
func Errorf(format string, a ...interface{}) error {
	err, wrap := lastError(format, a)
	if err == nil {
		return &noWrapError{Sprintf(format, a...), nil, errors.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 := Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...)
	frame := errors.Frame{}
	if internal.EnableTrace {
		frame = errors.Caller(1)
	}
	if wrap {
		return &wrapError{msg, err, frame}
	}
	return &noWrapError{msg, err, frame}
}

func lastError(format string, a []interface{}) (err error, wrap bool) {
	wrap = strings.HasSuffix(format, ": %w")
	if !wrap &&
		!strings.HasSuffix(format, ": %s") &&
		!strings.HasSuffix(format, ": %v") {
		return nil, false
	}

	if len(a) == 0 {
		return nil, false
	}

	err, ok := a[len(a)-1].(error)
	if !ok {
		return nil, false
	}

	return err, wrap
}

type noWrapError struct {
	msg   string
	err   error
	frame errors.Frame
}

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

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

type wrapError struct {
	msg   string
	err   error
	frame errors.Frame
}

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

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

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

func fmtError(p *pp, verb rune, err error) (handled bool) {
	var (
		sep = " " // separator before next error
		w   = p   // print buffer where error text is written
	)
	switch {
	// Note that this switch must match the preference order
	// for ordinary string printing (%#v before %+v, and so on).

	case p.fmt.sharpV:
		if stringer, ok := p.arg.(GoStringer); ok {
			// Print the result of GoString unadorned.
			p.fmt.fmtS(stringer.GoString())
			return true
		}
		return false

	case p.fmt.plusV:
		sep = "\n  - "
		w.fmt.fmtFlags = fmtFlags{plusV: p.fmt.plusV} // only keep detail flag

		// The width or precision of a detailed view could be the number of
		// errors to print from a list.

	default:
		// Use an intermediate buffer in the rare cases that precision,
		// truncation, or one of the alternative verbs (q, x, and X) are
		// specified.
		switch verb {
		case 's', 'v':
			if (!w.fmt.widPresent || w.fmt.wid == 0) && !w.fmt.precPresent {
				break
			}
			fallthrough
		case 'q', 'x', 'X':
			w = newPrinter()
			defer w.free()
		default:
			w.badVerb(verb)
			return true
		}
	}

loop:
	for {
		w.fmt.inDetail = false
		switch v := err.(type) {
		case errors.Formatter:
			err = v.Format((*errPP)(w))
		// TODO: This case is for supporting old error implementations.
		// It may eventually disappear.
		case interface{ FormatError(errors.Printer) error }:
			err = v.FormatError((*errPP)(w))
		case Formatter:
			// Discard verb, but keep the flags. Discarding the verb prevents
			// nested quoting and other unwanted behavior. Preserving flags
			// recursively signals a request for detail, if interpreted as %+v.
			w.fmt.fmtFlags = p.fmt.fmtFlags
			if w.fmt.plusV {
				v.Format((*errPPState)(w), 'v') // indent new lines
			} else {
				v.Format(w, 'v') // do not indent new lines
			}
			break loop
		default:
			w.fmtString(v.Error(), 's')
			break loop
		}
		if err == nil {
			break
		}
		if !w.fmt.inDetail || !p.fmt.plusV {
			w.buf.WriteByte(':')
		}
		// Strip last newline of detail.
		if bytes.HasSuffix([]byte(w.buf), detailSep) {
			w.buf = w.buf[:len(w.buf)-len(detailSep)]
		}
		w.buf.WriteString(sep)
		w.fmt.inDetail = false
	}

	if w != p {
		p.fmtString(string(w.buf), verb)
	}
	return true
}

var detailSep = []byte("\n    ")

// errPPState wraps a pp to implement State with indentation. It is used
// for errors implementing fmt.Formatter.
type errPPState pp

func (p *errPPState) Width() (wid int, ok bool)      { return (*pp)(p).Width() }
func (p *errPPState) Precision() (prec int, ok bool) { return (*pp)(p).Precision() }
func (p *errPPState) Flag(c int) bool                { return (*pp)(p).Flag(c) }

func (p *errPPState) Write(b []byte) (n int, err error) {
	if !p.fmt.inDetail || p.fmt.plusV {
		k := 0
		if p.fmt.indent {
			for i, c := range b {
				if c == '\n' {
					p.buf.Write(b[k:i])
					p.buf.Write(detailSep)
					k = i + 1
				}
			}
		}
		p.buf.Write(b[k:])
	}
	return len(b), nil
}

// errPP wraps a pp to implement an errors.Printer.
type errPP pp

func (p *errPP) Print(args ...interface{}) {
	if !p.fmt.inDetail || p.fmt.plusV {
		if p.fmt.indent {
			Fprint((*errPPState)(p), args...)
		} else {
			(*pp)(p).doPrint(args)
		}
	}
}

func (p *errPP) Printf(format string, args ...interface{}) {
	if !p.fmt.inDetail || p.fmt.plusV {
		if p.fmt.indent {
			Fprintf((*errPPState)(p), format, args...)
		} else {
			(*pp)(p).doPrintf(format, args)
		}
	}
}

func (p *errPP) Detail() bool {
	inDetail := p.fmt.inDetail
	p.fmt.inDetail = true
	p.fmt.indent = p.fmt.plusV
	if p.fmt.plusV && !inDetail {
		(*errPPState)(p).Write([]byte(":\n"))
	}
	return p.fmt.plusV
}
