// Copyright 2019 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 tkvtest contains a test harness for testing tkv.Storage implementations.
package tkvtest

import (
	"context"
	"fmt"
	"io"
	"testing"

	"golang.org/x/exp/sumdb/internal/tkv"
)

func TestStorage(t *testing.T, ctx context.Context, storage tkv.Storage) {
	s := storage

	// Insert records.
	err := s.ReadWrite(ctx, func(ctx context.Context, tx tkv.Transaction) error {
		for i := 0; i < 10; i++ {
			err := tx.BufferWrites([]tkv.Write{
				{Key: fmt.Sprint(i), Value: fmt.Sprint(-i)},
				{Key: fmt.Sprint(1000 + i), Value: fmt.Sprint(-1000 - i)},
			})
			if err != nil {
				t.Fatal(err)
			}
		}
		return nil
	})
	if err != nil {
		t.Fatal(err)
	}

	// Read the records back.
	testRead := func() {
		err := s.ReadOnly(ctx, func(ctx context.Context, tx tkv.Transaction) error {
			for i := int64(0); i < 1010; i++ {
				if i == 10 {
					i = 1000
				}
				val, err := tx.ReadValue(ctx, fmt.Sprint(i))
				if err != nil {
					t.Fatalf("reading %v: %v", i, err)
				}
				if val != fmt.Sprint(-i) {
					t.Fatalf("ReadValue %v = %q, want %v", i, val, fmt.Sprint(-i))
				}
			}
			return nil
		})
		if err != nil {
			t.Fatal(err)
		}
	}
	testRead()

	// Buffered writes in failed transaction should not be applied.
	err = s.ReadWrite(ctx, func(ctx context.Context, tx tkv.Transaction) error {
		tx.BufferWrites([]tkv.Write{
			{Key: fmt.Sprint(0), Value: ""},          // delete
			{Key: fmt.Sprint(1), Value: "overwrite"}, // overwrite
		})
		if err != nil {
			t.Fatal(err)
		}
		return io.ErrUnexpectedEOF
	})
	if err != io.ErrUnexpectedEOF {
		t.Fatalf("ReadWrite returned %v, want ErrUnexpectedEOF", err)
	}

	// All same values should still be there.
	testRead()
}
