package jws

import (
	"fmt"

	"github.com/SermoDigital/jose/crypto"
)

// VerifyCallback is a callback function that can be used to access header
// parameters to lookup needed information. For example, looking
// up the "kid" parameter.
// The return slice must be a slice of keys used in the verification
// of the JWS.
type VerifyCallback func(JWS) ([]interface{}, error)

// VerifyCallback validates the current JWS' signature as-is. It
// accepts a callback function that can be used to access header
// parameters to lookup needed information. For example, looking
// up the "kid" parameter.
// The return slice must be a slice of keys used in the verification
// of the JWS.
func (j *jws) VerifyCallback(fn VerifyCallback, methods []crypto.SigningMethod, o *SigningOpts) error {
	keys, err := fn(j)
	if err != nil {
		return err
	}
	return j.VerifyMulti(keys, methods, o)
}

// IsMultiError returns true if the given error is type *MultiError.
func IsMultiError(err error) bool {
	_, ok := err.(*MultiError)
	return ok
}

// MultiError is a slice of errors.
type MultiError []error

// Errors implements the error interface.
func (m *MultiError) Error() string {
	var s string
	var n int
	for _, err := range *m {
		if err != nil {
			if n == 0 {
				s = err.Error()
			}
			n++
		}
	}
	switch n {
	case 0:
		return ""
	case 1:
		return s
	case 2:
		return s + " and 1 other error"
	}
	return fmt.Sprintf("%s (and %d other errors)", s, n-1)
}

// Any means any of the JWS signatures need to verify.
// Refer to verifyMulti for more information.
const Any int = 0

// VerifyMulti verifies the current JWS as-is. Since it's meant to be
// called after parsing a stream of bytes into a JWS, it doesn't do any
// internal parsing like the Sign, Flat, Compact, or General methods do.
func (j *jws) VerifyMulti(keys []interface{}, methods []crypto.SigningMethod, o *SigningOpts) error {

	// Catch a simple mistake. Parameter o is irrelevant in this scenario.
	if len(keys) == 1 &&
		len(methods) == 1 &&
		len(j.sb) == 1 {
		return j.Verify(keys[0], methods[0])
	}

	if len(j.sb) != len(methods) {
		return ErrNotEnoughMethods
	}

	if len(keys) < 1 ||
		len(keys) > 1 && len(keys) != len(j.sb) {
		return ErrNotEnoughKeys
	}

	// TODO do this better.
	if len(keys) == 1 {
		k := keys[0]
		keys = make([]interface{}, len(methods))
		for i := range keys {
			keys[i] = k
		}
	}

	var o2 SigningOpts
	if o == nil {
		o = new(SigningOpts)
	}

	var m MultiError
	for i := range j.sb {
		err := j.sb[i].verify(j.plcache, keys[i], methods[i])
		if err != nil {
			m = append(m, err)
		} else {
			o2.Inc()
			if o.Needs(i) {
				o.ptr++
				o2.Append(i)
			}
		}
	}

	err := o.Validate(&o2)
	if err != nil {
		m = append(m, err)
	}
	if len(m) == 0 {
		return nil
	}
	return &m
}

// SigningOpts is a struct which holds options for validating
// JWS signatures.
// Number represents the cumulative which signatures need to verify
// in order for the JWS to be considered valid.
// Leave 'Number' empty or set it to the constant 'Any' if any number of
// valid signatures (greater than one) should verify the JWS.
//
// Use the indices of the signatures that need to verify in order
// for the JWS to be considered valid if specific signatures need
// to verify in order for the JWS to be considered valid.
//
// Note:
//     The JWS spec requires *at least* one
//     signature to verify in order for the JWS to be considered valid.
type SigningOpts struct {
	// Minimum of signatures which need to verify.
	Number int

	// Indices of specific signatures which need to verify.
	Indices []int
	ptr     int

	_ struct{}
}

// Append appends x to s' Indices member.
func (s *SigningOpts) Append(x int) {
	s.Indices = append(s.Indices, x)
}

// Needs returns true if x resides inside s' Indices member
// for the given index. It's used to match two SigningOpts Indices members.
func (s *SigningOpts) Needs(x int) bool {
	return s.ptr < len(s.Indices) && s.Indices[s.ptr] == x
}

// Inc increments s' Number member by one.
func (s *SigningOpts) Inc() { s.Number++ }

// Validate returns any errors found while validating the
// provided SigningOpts. The receiver validates |have|.
// It'll return an error if the passed SigningOpts' Number member is less
// than s' or if the passed SigningOpts' Indices slice isn't equal to s'.
func (s *SigningOpts) Validate(have *SigningOpts) error {
	if have.Number < s.Number ||
		(s.Indices != nil &&
			!eq(s.Indices, have.Indices)) {
		return ErrNotEnoughValidSignatures
	}
	return nil
}

func eq(a, b []int) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

// Verify verifies the current JWS as-is. Refer to verifyMulti
// for more information.
func (j *jws) Verify(key interface{}, method crypto.SigningMethod) error {
	if len(j.sb) < 1 {
		return ErrCannotValidate
	}
	return j.sb[0].verify(j.plcache, key, method)
}

func (s *sigHead) verify(pl []byte, key interface{}, method crypto.SigningMethod) error {
	if s.method.Alg() != method.Alg() || s.method.Hasher() != method.Hasher() {
		return ErrMismatchedAlgorithms
	}
	return method.Verify(format(s.Protected, pl), s.Signature, key)
}
