// Copyright 2024 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 storage

import (
	"fmt"
	"slices"
	"sync"
	"testing"
	"time"

	"golang.org/x/oscar/internal/testutil"
	"rsc.io/ordered"
)

// TestDB runs basic tests on db.
// It should be empty when TestDB is called.
// To run tests on Lock and Unlock, also call [TestDBLock].
func TestDB(t *testing.T, db DB) {
	db.Set([]byte("key"), []byte("value"))
	if val, ok := db.Get([]byte("key")); string(val) != "value" || ok != true {
		// unreachable except for bad db
		t.Fatalf("Get(key) = %q, %v, want %q, true", val, ok, "value")
	}
	if val, ok := db.Get([]byte("missing")); val != nil || ok != false {
		// unreachable except for bad db
		t.Fatalf("Get(missing) = %v, %v, want nil, false", val, ok)
	}

	testutil.StopPanic(func() {
		db.Set(nil, []byte{0})
		t.Fatal("Set with nil key did not panic")
	})

	db.Delete([]byte("key"))
	if val, ok := db.Get([]byte("key")); val != nil || ok != false {
		// unreachable except for bad db
		t.Fatalf("Get(key) after delete = %v, %v, want nil, false", val, ok)
	}

	b := db.Batch()
	for i := range 10 {
		b.Set(ordered.Encode(i), []byte(fmt.Sprint(i)))
		b.MaybeApply()
	}
	b.Apply()

	testutil.StopPanic(func() {
		b.Set(nil, []byte{0})
		t.Fatal("Set with nil key did not panic")
	})

	collect := func(min, max, stop int) []int {
		t.Helper()
		var list []int
		for key, val := range db.Scan(ordered.Encode(min), ordered.Encode(max)) {
			var i int
			if err := ordered.Decode(key, &i); err != nil {
				// unreachable except for bad db
				t.Fatalf("db.Scan malformed key %v", Fmt(key))
			}
			if sv, want := string(val()), fmt.Sprint(i); sv != want {
				// unreachable except for bad db
				t.Fatalf("db.Scan key %v val=%q, want %q", i, sv, want)
			}
			list = append(list, i)
			if i == stop {
				break
			}
		}
		return list
	}

	if scan, want := collect(3, 6, -1), []int{3, 4, 5, 6}; !slices.Equal(scan, want) {
		// unreachable except for bad db
		t.Fatalf("Scan(3, 6) = %v, want %v", scan, want)
	}

	if scan, want := collect(3, 6, 5), []int{3, 4, 5}; !slices.Equal(scan, want) {
		// unreachable except for bad db
		t.Fatalf("Scan(3, 6) with break at 5 = %v, want %v", scan, want)
	}

	// Passing a zero-length value for end to Scan will return an empty sequence.
	something := false
	for range db.Scan(nil, nil) {
		something = true
		break
	}
	if something {
		t.Fatal("Scan(nil, nil) returned a non-empty sequence, want an empty one")
	}

	db.DeleteRange(ordered.Encode(4), ordered.Encode(7))
	if scan, want := collect(-1, 11, -1), []int{0, 1, 2, 3, 8, 9}; !slices.Equal(scan, want) {
		// unreachable except for bad db
		t.Fatalf("Scan(-1, 11) after Delete(4, 7) = %v, want %v", scan, want)
	}

	b = db.Batch()
	for i := range 5 {
		b.Delete(ordered.Encode(i))
		b.Set(ordered.Encode(2*i), []byte(fmt.Sprint(2*i)))
	}
	b.DeleteRange(ordered.Encode(0), ordered.Encode(0))
	b.Apply()
	if scan, want := collect(-1, 11, -1), []int{6, 8, 9}; !slices.Equal(scan, want) {
		// unreachable except for bad db
		t.Fatalf("Scan(-1, 11) after batch Delete+Set = %v, want %v", scan, want)
	}

	// Check that batch.Apply clears the batch.
	k := ordered.Encode("a")
	b = db.Batch()
	b.Set(k, []byte{0})
	b.Apply()
	db.Delete(k)
	b.Apply() // should be a no-op
	if _, ok := db.Get(k); ok {
		t.Fatalf("empty Apply should be no-op, but got previous value")
	}

	// Can't test much, but check that it doesn't crash.
	db.Flush()
}

type locker interface {
	Lock(string)
	Unlock(string)
}

// TestDBLock verifies that Lock behaves correctly.
// It is separate from [TestDB] because it can't be used
// with a recorder/replayer, thanks to its sensitivity
// to time.
func TestDBLock(t *testing.T, db locker) {
	db.Lock("abc")
	c := make(chan struct{})
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		db.Lock("abc")
		close(c)
		db.Unlock("abc")
		wg.Done()
	}()

	// The db.Lock in the goroutine should block, since the lock is already held.
	select {
	case <-c:
		t.Fatal("Lock did not wait")
	case <-time.After(1 * time.Second):
	}

	db.Unlock("abc")

	// Now the db.Lock in the goroutine should return.
	<-c
	wg.Wait()

	testutil.StopPanic(func() {
		db.Unlock("def")
		t.Errorf("Unlock never-locked key did not panic")
	})
}
