// Copyright 2016 The Vanadium 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 internal

import (
	"bytes"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"encoding/gob"
	"strings"
	"testing"

	"v.io/v23/security"
	"v.io/v23/vom"
)

func vomEncode(b *testing.B, value interface{}) {
	// Try encoding once to make sure it succeeds.
	if _, err := vom.Encode(value); err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if _, err := vom.Encode(value); err != nil {
			b.Fatal(err)
		}
	}
}

func vomDecode(b *testing.B, value interface{}, make func() interface{}) {
	// Encode once to get the data, and decode once to make sure it succeeds.
	data, err := vom.Encode(value)
	if err != nil {
		b.Fatal(err)
	}
	if err := vom.Decode(data, make()); err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if err := vom.Decode(data, make()); err != nil {
			b.Fatal(err)
		}
	}
}

func vomEncodeMany(b *testing.B, value interface{}) {
	var buf bytes.Buffer
	enc := vom.NewEncoder(&buf)
	// Encode once first to write the type and value.
	if err := enc.Encode(value); err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		buf.Reset()
		if err := enc.Encode(value); err != nil {
			b.Fatal(err)
		}
	}
}

func vomDecodeMany(b *testing.B, value interface{}, make func() interface{}) {
	var buf bytes.Buffer
	enc := vom.NewEncoder(&buf)
	// Encode once first to write the type and value.
	if err := enc.Encode(value); err != nil {
		b.Fatal(err)
	}
	// Capture the offset, and encode again to write just the value.
	valueOffset := int64(buf.Len())
	if err := enc.Encode(value); err != nil {
		b.Fatal(err)
	}
	// Decode twice to read the type and two values.  We must read both values to
	// ensure the decoder doesn't have any additional buffered data.
	reader := bytes.NewReader(buf.Bytes())
	dec := vom.NewDecoder(reader)
	for i := 0; i < 2; i++ {
		if err := dec.Decode(make()); err != nil {
			b.Fatal(err)
		}
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		reader.Seek(valueOffset, 0)
		if err := dec.Decode(make()); err != nil {
			b.Fatal(err)
		}
	}
}

func gobEncode(b *testing.B, value interface{}) {
	// Try encoding once to make sure it succeeds.
	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(value); err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		buf.Reset()
		if err := gob.NewEncoder(&buf).Encode(value); err != nil {
			b.Fatal(err)
		}
	}
}

func gobDecode(b *testing.B, value interface{}, make func() interface{}) {
	// Encode once to get the data, and decode once to make sure it succeeds.
	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(value); err != nil {
		b.Fatal(err)
	}
	reader := bytes.NewReader(buf.Bytes())
	if err := gob.NewDecoder(reader).Decode(make()); err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		reader.Seek(0, 0)
		if err := gob.NewDecoder(reader).Decode(make()); err != nil {
			b.Fatal(err)
		}
	}
}

func gobEncodeMany(b *testing.B, value interface{}) {
	var buf bytes.Buffer
	enc := gob.NewEncoder(&buf)
	// Encode once first to write the type.
	if err := enc.Encode(value); err != nil {
		b.Fatal(err)
	}
	enc.Encode(value)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		buf.Reset()
		if err := enc.Encode(value); err != nil {
			b.Fatal(err)
		}
	}
}

func gobDecodeMany(b *testing.B, value interface{}, make func() interface{}) {
	var buf bytes.Buffer
	enc := gob.NewEncoder(&buf)
	// Encode once first to write the type and value.
	if err := enc.Encode(value); err != nil {
		b.Fatal(err)
	}
	// Capture the offset, and encode again to write just the value.
	valueOffset := int64(buf.Len())
	if err := enc.Encode(value); err != nil {
		b.Fatal(err)
	}
	// Decode twice to read the type and two values.  We must read both values to
	// ensure the decoder doesn't have any additional buffered data.
	reader := bytes.NewReader(buf.Bytes())
	dec := gob.NewDecoder(reader)
	for i := 0; i < 2; i++ {
		if err := dec.Decode(make()); err != nil {
			b.Fatal(err)
		}
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		reader.Seek(valueOffset, 0)
		if err := dec.Decode(make()); err != nil {
			b.Fatal(err)
		}
	}
}

func createString(length int) string {
	return strings.Repeat("a", length)
}

func createByteList(length int) []byte {
	return []byte(strings.Repeat("a", length))
}

func createList(length int) []int32 {
	l := make([]int32, length)
	for i := range l {
		l[i] = int32(i)
	}
	return l
}

func createListAny(length int) []*vom.RawBytes {
	l := make([]*vom.RawBytes, length)
	for i := range l {
		l[i] = vom.RawBytesOf(i)
	}
	return l
}

func newSigner() security.Signer {
	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		panic(err)
	}
	return security.NewInMemoryECDSASigner(key)
}

// createTypicalBlessings creates a blessings with certificate structures and
// caveats that are "common": a chain of 3 certificates for the user, with a
// third-party caveat used for revocation.
func createTypicalBlessings() security.Blessings {
	var (
		p1, _  = security.CreatePrincipal(newSigner(), nil, nil)
		p2, _  = security.CreatePrincipal(newSigner(), nil, nil)
		p3, _  = security.CreatePrincipal(newSigner(), nil, nil)
		tpc, _ = security.NewPublicKeyCaveat(p2.PublicKey(), "some_location", security.ThirdPartyRequirements{}, security.UnconstrainedUse())

		b1, _ = p1.BlessSelf("root")
		b2, _ = p1.Bless(p2.PublicKey(), b1, "u", security.UnconstrainedUse())
		b3, _ = p2.Bless(p3.PublicKey(), b2, "user", tpc)
	)
	return b3
}
