package verify

import (
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/sha256"
	"io"
	"testing"
	"time"

	"github.com/flynn/go-tuf/data"
	"github.com/flynn/go-tuf/sign"
	"golang.org/x/crypto/ed25519"

	. "gopkg.in/check.v1"
)

// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }

type VerifySuite struct{}

var _ = Suite(&VerifySuite{})

type ecdsaSigner struct {
	*ecdsa.PrivateKey
}

func (s ecdsaSigner) PublicData() *data.Key {
	pub := s.Public().(*ecdsa.PublicKey)
	return &data.Key{
		Type:  data.KeyTypeECDSA_SHA2_P256,
		Value: data.KeyValue{Public: elliptic.Marshal(pub.Curve, pub.X, pub.Y)},
	}
}

func (s ecdsaSigner) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
	hash := sha256.Sum256(msg)
	return s.PrivateKey.Sign(rand, hash[:], crypto.SHA256)
}

func (s ecdsaSigner) IDs() []string {
	return s.PublicData().IDs()
}

func (s ecdsaSigner) ContainsID(id string) bool {
	return s.PublicData().ContainsID(id)
}

func (ecdsaSigner) Type() string {
	return data.KeyTypeECDSA_SHA2_P256
}

func (VerifySuite) Test(c *C) {
	type test struct {
		name  string
		keys  []*data.Key
		roles map[string]*data.Role
		s     *data.Signed
		ver   int
		exp   *time.Time
		typ   string
		role  string
		err   error
		mut   func(*test)
	}

	expiredTime := time.Now().Add(-time.Hour)
	minVer := 10
	tests := []test{
		{
			name: "no signatures",
			mut:  func(t *test) { t.s.Signatures = []data.Signature{} },
			err:  ErrNoSignatures,
		},
		{
			name: "unknown role",
			role: "foo",
			err:  ErrUnknownRole{"foo"},
		},
		{
			name: "signature wrong length",
			mut:  func(t *test) { t.s.Signatures[0].Signature = []byte{0} },
			err:  ErrInvalid,
		},
		{
			name: "key missing from role",
			mut:  func(t *test) { t.roles["root"].KeyIDs = nil },
			err:  ErrRoleThreshold{1, 0},
		},
		{
			name: "invalid signature",
			mut:  func(t *test) { t.s.Signatures[0].Signature = make([]byte, ed25519.SignatureSize) },
			err:  ErrInvalid,
		},
		{
			name: "not enough signatures",
			mut:  func(t *test) { t.roles["root"].Threshold = 2 },
			err:  ErrRoleThreshold{2, 1},
		},
		{
			name: "exactly enough signatures",
		},
		{
			name: "more than enough signatures",
			mut: func(t *test) {
				k, _ := sign.GenerateEd25519Key()
				sign.Sign(t.s, k.Signer())
				t.keys = append(t.keys, k.PublicData())
				t.roles["root"].KeyIDs = append(t.roles["root"].KeyIDs, k.PublicData().IDs()...)
			},
		},
		{
			name: "duplicate key id",
			mut: func(t *test) {
				t.roles["root"].Threshold = 2
				t.s.Signatures = append(t.s.Signatures, t.s.Signatures[0])
			},
			err: ErrRoleThreshold{2, 1},
		},
		{
			name: "unknown key",
			mut: func(t *test) {
				k, _ := sign.GenerateEd25519Key()
				sign.Sign(t.s, k.Signer())
			},
		},
		{
			name: "unknown key below threshold",
			mut: func(t *test) {
				k, _ := sign.GenerateEd25519Key()
				sign.Sign(t.s, k.Signer())
				t.roles["root"].Threshold = 2
			},
			err: ErrRoleThreshold{2, 1},
		},
		{
			name: "unknown keys in db",
			mut: func(t *test) {
				k, _ := sign.GenerateEd25519Key()
				sign.Sign(t.s, k.Signer())
				t.keys = append(t.keys, k.PublicData())
			},
		},
		{
			name: "unknown keys in db below threshold",
			mut: func(t *test) {
				k, _ := sign.GenerateEd25519Key()
				sign.Sign(t.s, k.Signer())
				t.keys = append(t.keys, k.PublicData())
				t.roles["root"].Threshold = 2
			},
			err: ErrRoleThreshold{2, 1},
		},
		{
			name: "wrong type",
			typ:  "bar",
			err:  ErrWrongMetaType,
		},
		{
			name: "low version",
			ver:  minVer - 1,
			err:  ErrLowVersion{minVer - 1, minVer},
		},
		{
			name: "expired",
			exp:  &expiredTime,
			err:  ErrExpired{expiredTime},
		},
		{
			name: "valid ecdsa signature",
			mut: func(t *test) {
				k, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
				s := ecdsaSigner{k}
				sign.Sign(t.s, s)
				t.s.Signatures = t.s.Signatures[1:]
				t.keys = []*data.Key{s.PublicData()}
				t.roles["root"].KeyIDs = s.PublicData().IDs()
			},
		},
		{
			name: "invalid ecdsa signature",
			mut: func(t *test) {
				k, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
				s := ecdsaSigner{k}
				sign.Sign(t.s, s)
				t.s.Signatures[1].Signature[0]++
				t.keys = append(t.keys, s.PublicData())
				t.roles["root"].KeyIDs = append(t.roles["root"].KeyIDs, s.PublicData().IDs()...)
			},
			err: ErrInvalid,
		},
	}
	for _, t := range tests {
		if t.role == "" {
			t.role = "root"
		}
		if t.ver == 0 {
			t.ver = minVer
		}
		if t.exp == nil {
			expires := time.Now().Add(time.Hour)
			t.exp = &expires
		}
		if t.typ == "" {
			t.typ = t.role
		}
		if t.keys == nil && t.s == nil {
			k, _ := sign.GenerateEd25519Key()
			t.s, _ = sign.Marshal(&signedMeta{Type: t.typ, Version: t.ver, Expires: *t.exp}, k.Signer())
			t.keys = []*data.Key{k.PublicData()}
		}
		if t.roles == nil {
			t.roles = map[string]*data.Role{
				"root": {
					KeyIDs:    t.keys[0].IDs(),
					Threshold: 1,
				},
			}
		}
		if t.mut != nil {
			t.mut(&t)
		}

		db := NewDB()
		for _, k := range t.keys {
			for _, id := range k.IDs() {
				err := db.AddKey(id, k)
				c.Assert(err, IsNil)
			}
		}
		for n, r := range t.roles {
			err := db.AddRole(n, r)
			c.Assert(err, IsNil)
		}

		err := db.Verify(t.s, t.role, minVer)
		if e, ok := t.err.(ErrExpired); ok {
			assertErrExpired(c, err, e)
		} else {
			c.Assert(err, DeepEquals, t.err, Commentf("name = %s", t.name))
		}
	}
}

func assertErrExpired(c *C, err error, expected ErrExpired) {
	actual, ok := err.(ErrExpired)
	if !ok {
		c.Fatalf("expected err to have type ErrExpired, got %T", err)
	}
	c.Assert(actual.Expired.Unix(), Equals, expected.Expired.Unix())
}
