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

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"math/big"
	"net"
	"testing"
	"time"
)

func BenchmarkTLSConnectionEstablishment(b *testing.B) {
	client, server, err := newTLSConfigs()
	if err != nil {
		b.Fatal(err)
	}
	ln, err := tls.Listen("tcp4", "127.0.0.1:0", server)
	if err != nil {
		b.Fatal(err)
	}
	defer ln.Close()
	go func() {
		buf := make([]byte, 1)
		for {
			c, err := ln.Accept()
			if err != nil {
				return
			}
			if n, err := c.Read(buf); n != 1 {
				b.Fatal("Got (%d, %v), expected (1, <nil or io.EOF>)", n, err)
			}
			if _, err := c.Write(buf); err != nil {
				return
			}
			c.Close()
		}
	}()
	network, addr := ln.Addr().Network(), ln.Addr().String()
	buf := []byte{'A'}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		c, err := tls.Dial(network, addr, client)
		if err != nil {
			b.Fatalf("%d/%d: %v", i, b.N, err)
		}
		if _, err := c.Write(buf); err != nil {
			b.Fatalf("%d/%d: %v", i, b.N, err)
		}
		buf[0] = 'B'
		if n, err := c.Read(buf); n != 1 {
			b.Fatalf("%d/%d: Got (%d, %v), want (1, <nil or io.EOF>)", i, b.N, n, err)
		}
		if buf[0] != 'A' {
			b.Fatalf("%d/%d: Got %d, want %d", i, b.N, buf[0], 'A')
		}
		// Close the connection to prevent hitting the ulimit on open
		// file descriptors.
		if err := c.Close(); err != nil {
			b.Fatal(err)
		}
	}
	b.StopTimer()
}

// Ideally this benchmark wouldn't be required having just
// BenchmarkTLSConnectionEstablishment would suffice - the two should have very
// similar run times.
//
// Hoever, on some machines I was having trouble getting consistent numbers
// with BenchmarkTLSConnectionEstablishment - possibly becuase of some
// network monitoring software installed on those. Till that is figured out,
// have this additional benchmark that measures just the CPU work done for
// mutual TLS authentication.
func BenchmarkTLSHandshake(b *testing.B) {
	client, server := net.Pipe()
	defer client.Close()
	defer server.Close()
	clientCfg, serverCfg, err := newTLSConfigs()
	if err != nil {
		b.Fatal(err)
	}
	ch := make(chan *tls.Conn)
	go func() {
		for c := range ch {
			c.Handshake()
		}
	}()
	defer close(ch)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		ch <- tls.Client(client, clientCfg)
		serverConn := tls.Server(server, serverCfg)
		// Use the server's Handshake and not the client's here since
		// the TLS handshake ends with the server verifying the
		// client's certificate. If we used the client's Handshake then
		// server verification time would be excluded from this loop.
		if err := serverConn.Handshake(); err != nil {
			b.Fatal(err)
		}
		if !serverConn.ConnectionState().HandshakeComplete {
			b.Fatal("Handshake not completed!")
		}
	}
}

func newTLSConfigs() (client, server *tls.Config, err error) {
	certpool := x509.NewCertPool()
	serverCert, err := newTLSCert(certpool)
	if err != nil {
		return nil, nil, err
	}
	clientCert, err := newTLSCert(certpool)
	if err != nil {
		return nil, nil, err
	}
	server = &tls.Config{
		Certificates:           []tls.Certificate{serverCert},
		ClientCAs:              certpool,
		ClientAuth:             tls.RequireAndVerifyClientCert,
		SessionTicketsDisabled: true,
	}
	client = &tls.Config{
		Certificates:           []tls.Certificate{clientCert},
		RootCAs:                certpool,
		ServerName:             "127.0.0.1",
		SessionTicketsDisabled: true,
	}
	return client, server, nil
}

func newTLSCert(pool *x509.CertPool) (tls.Certificate, error) {
	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		return tls.Certificate{}, err
	}
	template := &x509.Certificate{
		SerialNumber:          big.NewInt(1),
		NotBefore:             time.Now().Add(-24 * time.Hour),
		NotAfter:              time.Now().Add(24 * time.Hour),
		BasicConstraintsValid: true,
		IsCA:        true,
		IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
	}
	certBytes, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
	if err != nil {
		return tls.Certificate{}, err
	}
	x509Cert, err := x509.ParseCertificate(certBytes)
	if err != nil {
		return tls.Certificate{}, err
	}
	pool.AddCert(x509Cert)
	return tls.Certificate{
		Certificate: [][]byte{certBytes},
		PrivateKey:  priv,
		Leaf:        x509Cert, // Set to avoid per-handshake calls to x509.ParseCertificate
	}, nil
}
