package backend

import (
	"reflect"
	"sort"
	"testing"

	uuid "github.com/hashicorp/go-uuid"
	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/hcl/v2/hcldec"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs"
	"github.com/hashicorp/terraform/internal/configs/hcl2shim"
	"github.com/hashicorp/terraform/internal/states"
	"github.com/hashicorp/terraform/internal/states/statemgr"
	"github.com/hashicorp/terraform/internal/tfdiags"
)

// TestBackendConfig validates and configures the backend with the
// given configuration.
func TestBackendConfig(t *testing.T, b Backend, c hcl.Body) Backend {
	t.Helper()

	t.Logf("TestBackendConfig on %T with %#v", b, c)

	var diags tfdiags.Diagnostics

	// To make things easier for test authors, we'll allow a nil body here
	// (even though that's not normally valid) and just treat it as an empty
	// body.
	if c == nil {
		c = hcl.EmptyBody()
	}

	schema := b.ConfigSchema()
	spec := schema.DecoderSpec()
	obj, decDiags := hcldec.Decode(c, spec, nil)
	diags = diags.Append(decDiags)

	newObj, valDiags := b.PrepareConfig(obj)
	diags = diags.Append(valDiags.InConfigBody(c, ""))

	// it's valid for a Backend to have warnings (e.g. a Deprecation) as such we should only raise on errors
	if diags.HasErrors() {
		t.Fatal(diags.ErrWithWarnings())
	}

	obj = newObj

	confDiags := b.Configure(obj)
	if len(confDiags) != 0 {
		confDiags = confDiags.InConfigBody(c, "")
		t.Fatal(confDiags.ErrWithWarnings())
	}

	return b
}

// TestWrapConfig takes a raw data structure and converts it into a
// synthetic hcl.Body to use for testing.
//
// The given structure should only include values that can be accepted by
// hcl2shim.HCL2ValueFromConfigValue. If incompatible values are given,
// this function will panic.
func TestWrapConfig(raw map[string]interface{}) hcl.Body {
	obj := hcl2shim.HCL2ValueFromConfigValue(raw)
	return configs.SynthBody("<TestWrapConfig>", obj.AsValueMap())
}

// TestBackend will test the functionality of a Backend. The backend is
// assumed to already be configured. This will test state functionality.
// If the backend reports it doesn't support multi-state by returning the
// error ErrWorkspacesNotSupported, then it will not test that.
func TestBackendStates(t *testing.T, b Backend) {
	t.Helper()

	noDefault := false
	if _, err := b.StateMgr(DefaultStateName); err != nil {
		if err == ErrDefaultWorkspaceNotSupported {
			noDefault = true
		} else {
			t.Fatalf("error: %v", err)
		}
	}

	workspaces, err := b.Workspaces()
	if err != nil {
		if err == ErrWorkspacesNotSupported {
			t.Logf("TestBackend: workspaces not supported in %T, skipping", b)
			return
		}
		t.Fatalf("error: %v", err)
	}

	// Test it starts with only the default
	if !noDefault && (len(workspaces) != 1 || workspaces[0] != DefaultStateName) {
		t.Fatalf("should only have the default workspace to start: %#v", workspaces)
	}

	// Create a couple states
	foo, err := b.StateMgr("foo")
	if err != nil {
		t.Fatalf("error: %s", err)
	}
	if err := foo.RefreshState(); err != nil {
		t.Fatalf("bad: %s", err)
	}
	if v := foo.State(); v.HasManagedResourceInstanceObjects() {
		t.Fatalf("should be empty: %s", v)
	}

	bar, err := b.StateMgr("bar")
	if err != nil {
		t.Fatalf("error: %s", err)
	}
	if err := bar.RefreshState(); err != nil {
		t.Fatalf("bad: %s", err)
	}
	if v := bar.State(); v.HasManagedResourceInstanceObjects() {
		t.Fatalf("should be empty: %s", v)
	}

	// Verify they are distinct states that can be read back from storage
	{
		// We'll use two distinct states here and verify that changing one
		// does not also change the other.
		fooState := states.NewState()
		barState := states.NewState()

		// write a known state to foo
		if err := foo.WriteState(fooState); err != nil {
			t.Fatal("error writing foo state:", err)
		}
		if err := foo.PersistState(nil); err != nil {
			t.Fatal("error persisting foo state:", err)
		}

		// We'll make "bar" different by adding a fake resource state to it.
		barState.SyncWrapper().SetResourceInstanceCurrent(
			addrs.ResourceInstance{
				Resource: addrs.Resource{
					Mode: addrs.ManagedResourceMode,
					Type: "test_thing",
					Name: "foo",
				},
			}.Absolute(addrs.RootModuleInstance),
			&states.ResourceInstanceObjectSrc{
				AttrsJSON:     []byte("{}"),
				Status:        states.ObjectReady,
				SchemaVersion: 0,
			},
			addrs.AbsProviderConfig{
				Provider: addrs.NewDefaultProvider("test"),
				Module:   addrs.RootModule,
			},
		)

		// write a distinct known state to bar
		if err := bar.WriteState(barState); err != nil {
			t.Fatalf("bad: %s", err)
		}
		if err := bar.PersistState(nil); err != nil {
			t.Fatalf("bad: %s", err)
		}

		// verify that foo is unchanged with the existing state manager
		if err := foo.RefreshState(); err != nil {
			t.Fatal("error refreshing foo:", err)
		}
		fooState = foo.State()
		if fooState.HasManagedResourceInstanceObjects() {
			t.Fatal("after writing a resource to bar, foo now has resources too")
		}

		// fetch foo again from the backend
		foo, err = b.StateMgr("foo")
		if err != nil {
			t.Fatal("error re-fetching state:", err)
		}
		if err := foo.RefreshState(); err != nil {
			t.Fatal("error refreshing foo:", err)
		}
		fooState = foo.State()
		if fooState.HasManagedResourceInstanceObjects() {
			t.Fatal("after writing a resource to bar and re-reading foo, foo now has resources too")
		}

		// fetch the bar again from the backend
		bar, err = b.StateMgr("bar")
		if err != nil {
			t.Fatal("error re-fetching state:", err)
		}
		if err := bar.RefreshState(); err != nil {
			t.Fatal("error refreshing bar:", err)
		}
		barState = bar.State()
		if !barState.HasManagedResourceInstanceObjects() {
			t.Fatal("after writing a resource instance object to bar and re-reading it, the object has vanished")
		}
	}

	// Verify we can now list them
	{
		// we determined that named stated are supported earlier
		workspaces, err := b.Workspaces()
		if err != nil {
			t.Fatalf("err: %s", err)
		}

		sort.Strings(workspaces)
		expected := []string{"bar", "default", "foo"}
		if noDefault {
			expected = []string{"bar", "foo"}
		}
		if !reflect.DeepEqual(workspaces, expected) {
			t.Fatalf("wrong workspaces list\ngot:  %#v\nwant: %#v", workspaces, expected)
		}
	}

	// Delete some workspaces
	if err := b.DeleteWorkspace("foo", true); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Verify the default state can't be deleted
	if err := b.DeleteWorkspace(DefaultStateName, true); err == nil {
		t.Fatal("expected error")
	}

	// Create and delete the foo workspace again.
	// Make sure that there are no leftover artifacts from a deleted state
	// preventing re-creation.
	foo, err = b.StateMgr("foo")
	if err != nil {
		t.Fatalf("error: %s", err)
	}
	if err := foo.RefreshState(); err != nil {
		t.Fatalf("bad: %s", err)
	}
	if v := foo.State(); v.HasManagedResourceInstanceObjects() {
		t.Fatalf("should be empty: %s", v)
	}
	// and delete it again
	if err := b.DeleteWorkspace("foo", true); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Verify deletion
	{
		workspaces, err := b.Workspaces()
		if err != nil {
			t.Fatalf("err: %s", err)
		}

		sort.Strings(workspaces)
		expected := []string{"bar", "default"}
		if noDefault {
			expected = []string{"bar"}
		}
		if !reflect.DeepEqual(workspaces, expected) {
			t.Fatalf("wrong workspaces list\ngot:  %#v\nwant: %#v", workspaces, expected)
		}
	}
}

// TestBackendStateLocks will test the locking functionality of the remote
// state backend.
func TestBackendStateLocks(t *testing.T, b1, b2 Backend) {
	t.Helper()
	testLocks(t, b1, b2, false)
}

// TestBackendStateForceUnlock verifies that the lock error is the expected
// type, and the lock can be unlocked using the ID reported in the error.
// Remote state backends that support -force-unlock should call this in at
// least one of the acceptance tests.
func TestBackendStateForceUnlock(t *testing.T, b1, b2 Backend) {
	t.Helper()
	testLocks(t, b1, b2, true)
}

// TestBackendStateLocksInWS will test the locking functionality of the remote
// state backend.
func TestBackendStateLocksInWS(t *testing.T, b1, b2 Backend, ws string) {
	t.Helper()
	testLocksInWorkspace(t, b1, b2, false, ws)
}

// TestBackendStateForceUnlockInWS verifies that the lock error is the expected
// type, and the lock can be unlocked using the ID reported in the error.
// Remote state backends that support -force-unlock should call this in at
// least one of the acceptance tests.
func TestBackendStateForceUnlockInWS(t *testing.T, b1, b2 Backend, ws string) {
	t.Helper()
	testLocksInWorkspace(t, b1, b2, true, ws)
}

func testLocks(t *testing.T, b1, b2 Backend, testForceUnlock bool) {
	testLocksInWorkspace(t, b1, b2, testForceUnlock, DefaultStateName)
}

func testLocksInWorkspace(t *testing.T, b1, b2 Backend, testForceUnlock bool, workspace string) {
	t.Helper()

	// Get the default state for each
	b1StateMgr, err := b1.StateMgr(DefaultStateName)
	if err != nil {
		t.Fatalf("error: %s", err)
	}
	if err := b1StateMgr.RefreshState(); err != nil {
		t.Fatalf("bad: %s", err)
	}

	// Fast exit if this doesn't support locking at all
	if _, ok := b1StateMgr.(statemgr.Locker); !ok {
		t.Logf("TestBackend: backend %T doesn't support state locking, not testing", b1)
		return
	}

	t.Logf("TestBackend: testing state locking for %T", b1)

	b2StateMgr, err := b2.StateMgr(DefaultStateName)
	if err != nil {
		t.Fatalf("error: %s", err)
	}
	if err := b2StateMgr.RefreshState(); err != nil {
		t.Fatalf("bad: %s", err)
	}

	// Reassign so its obvious whats happening
	lockerA := b1StateMgr.(statemgr.Locker)
	lockerB := b2StateMgr.(statemgr.Locker)

	infoA := statemgr.NewLockInfo()
	infoA.Operation = "test"
	infoA.Who = "clientA"

	infoB := statemgr.NewLockInfo()
	infoB.Operation = "test"
	infoB.Who = "clientB"

	lockIDA, err := lockerA.Lock(infoA)
	if err != nil {
		t.Fatal("unable to get initial lock:", err)
	}

	// Make sure we can still get the statemgr.Full from another instance even
	// when locked.  This should only happen when a state is loaded via the
	// backend, and as a remote state.
	_, err = b2.StateMgr(DefaultStateName)
	if err != nil {
		t.Errorf("failed to read locked state from another backend instance: %s", err)
	}

	// If the lock ID is blank, assume locking is disabled
	if lockIDA == "" {
		t.Logf("TestBackend: %T: empty string returned for lock, assuming disabled", b1)
		return
	}

	_, err = lockerB.Lock(infoB)
	if err == nil {
		lockerA.Unlock(lockIDA)
		t.Fatal("client B obtained lock while held by client A")
	}

	if err := lockerA.Unlock(lockIDA); err != nil {
		t.Fatal("error unlocking client A", err)
	}

	lockIDB, err := lockerB.Lock(infoB)
	if err != nil {
		t.Fatal("unable to obtain lock from client B")
	}

	if lockIDB == lockIDA {
		t.Errorf("duplicate lock IDs: %q", lockIDB)
	}

	if err = lockerB.Unlock(lockIDB); err != nil {
		t.Fatal("error unlocking client B:", err)
	}

	// test the equivalent of -force-unlock, by using the id from the error
	// output.
	if !testForceUnlock {
		return
	}

	// get a new ID
	infoA.ID, err = uuid.GenerateUUID()
	if err != nil {
		panic(err)
	}

	lockIDA, err = lockerA.Lock(infoA)
	if err != nil {
		t.Fatal("unable to get re lock A:", err)
	}
	unlock := func() {
		err := lockerA.Unlock(lockIDA)
		if err != nil {
			t.Fatal(err)
		}
	}

	_, err = lockerB.Lock(infoB)
	if err == nil {
		unlock()
		t.Fatal("client B obtained lock while held by client A")
	}

	infoErr, ok := err.(*statemgr.LockError)
	if !ok {
		unlock()
		t.Fatalf("expected type *statemgr.LockError, got : %#v", err)
	}

	// try to unlock with the second unlocker, using the ID from the error
	if err := lockerB.Unlock(infoErr.Info.ID); err != nil {
		unlock()
		t.Fatalf("could not unlock with the reported ID %q: %s", infoErr.Info.ID, err)
	}
}
