// Copyright 2022 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 tls

import (
	"encoding/pem"
	"fmt"
	"runtime"
	"testing"
	"time"
)

func TestCertCache(t *testing.T) {
	cc := certCache{}
	p, _ := pem.Decode([]byte(rsaCertPEM))
	if p == nil {
		t.Fatal("Failed to decode certificate")
	}

	certA, err := cc.newCert(p.Bytes)
	if err != nil {
		t.Fatalf("newCert failed: %s", err)
	}
	certB, err := cc.newCert(p.Bytes)
	if err != nil {
		t.Fatalf("newCert failed: %s", err)
	}
	if certA.cert != certB.cert {
		t.Fatal("newCert returned a unique reference for a duplicate certificate")
	}

	if entry, ok := cc.Load(string(p.Bytes)); !ok {
		t.Fatal("cache does not contain expected entry")
	} else {
		if refs := entry.(*cacheEntry).refs.Load(); refs != 2 {
			t.Fatalf("unexpected number of references: got %d, want 2", refs)
		}
	}

	timeoutRefCheck := func(t *testing.T, key string, count int64) {
		t.Helper()
		c := time.After(4 * time.Second)
		for {
			select {
			case <-c:
				t.Fatal("timed out waiting for expected ref count")
			default:
				e, ok := cc.Load(key)
				if !ok && count != 0 {
					t.Fatal("cache does not contain expected key")
				} else if count == 0 && !ok {
					return
				}

				if e.(*cacheEntry).refs.Load() == count {
					return
				}
			}
		}
	}

	// Keep certA alive until at least now, so that we can
	// purposefully nil it and force the finalizer to be
	// called.
	runtime.KeepAlive(certA)
	certA = nil
	runtime.GC()

	timeoutRefCheck(t, string(p.Bytes), 1)

	// Keep certB alive until at least now, so that we can
	// purposefully nil it and force the finalizer to be
	// called.
	runtime.KeepAlive(certB)
	certB = nil
	runtime.GC()

	timeoutRefCheck(t, string(p.Bytes), 0)
}

func BenchmarkCertCache(b *testing.B) {
	p, _ := pem.Decode([]byte(rsaCertPEM))
	if p == nil {
		b.Fatal("Failed to decode certificate")
	}

	cc := certCache{}
	b.ReportAllocs()
	b.ResetTimer()
	// We expect that calling newCert additional times after
	// the initial call should not cause additional allocations.
	for extra := 0; extra < 4; extra++ {
		b.Run(fmt.Sprint(extra), func(b *testing.B) {
			actives := make([]*activeCert, extra+1)
			b.ResetTimer()
			for i := 0; i < b.N; i++ {
				var err error
				actives[0], err = cc.newCert(p.Bytes)
				if err != nil {
					b.Fatal(err)
				}
				for j := 0; j < extra; j++ {
					actives[j+1], err = cc.newCert(p.Bytes)
					if err != nil {
						b.Fatal(err)
					}
				}
				for j := 0; j < extra+1; j++ {
					actives[j] = nil
				}
				runtime.GC()
			}
		})
	}
}
