// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package statemgr

import (
	"reflect"
	"testing"

	"github.com/davecgh/go-spew/spew"
	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/states"
	"github.com/hashicorp/terraform/internal/states/statefile"
)

// TestFull is a helper for testing full state manager implementations. It
// expects that the given implementation is pre-loaded with a snapshot of the
// result from TestFullInitialState.
//
// If the given state manager also implements PersistentMeta, this function
// will test that the snapshot metadata changes as expected between calls
// to the methods of Persistent.
func TestFull(t *testing.T, s Full) {
	t.Helper()

	if err := s.RefreshState(); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Check that the initial state is correct.
	// These do have different Lineages, but we will replace current below.
	initial := TestFullInitialState()
	if state := s.State(); !state.Equal(initial) {
		t.Fatalf("state does not match expected initial state\n\ngot:\n%s\nwant:\n%s", spew.Sdump(state), spew.Sdump(initial))
	}

	var initialMeta SnapshotMeta
	if sm, ok := s.(PersistentMeta); ok {
		initialMeta = sm.StateSnapshotMeta()
	}

	// Now we've proven that the state we're starting with is an initial
	// state, we'll complete our work here with that state, since otherwise
	// further writes would violate the invariant that we only try to write
	// states that share the same lineage as what was initially written.
	current := s.State()

	// Write a new state and verify that we have it
	current.RootModule().SetOutputValue("bar", cty.StringVal("baz"), false)

	if err := s.WriteState(current); err != nil {
		t.Fatalf("err: %s", err)
	}

	if actual := s.State(); !actual.Equal(current) {
		t.Fatalf("bad:\n%#v\n\n%#v", actual, current)
	}

	// Test persistence
	if err := s.PersistState(nil); err != nil {
		t.Fatalf("err: %s", err)
	}

	// Refresh if we got it
	if err := s.RefreshState(); err != nil {
		t.Fatalf("err: %s", err)
	}

	var newMeta SnapshotMeta
	if sm, ok := s.(PersistentMeta); ok {
		newMeta = sm.StateSnapshotMeta()
		if got, want := newMeta.Lineage, initialMeta.Lineage; got != want {
			t.Errorf("Lineage changed from %q to %q", want, got)
		}
		if after, before := newMeta.Serial, initialMeta.Serial; after == before {
			t.Errorf("Serial didn't change from %d after new module added", before)
		}
	}

	// Same serial
	serial := newMeta.Serial
	if err := s.WriteState(current); err != nil {
		t.Fatalf("err: %s", err)
	}
	if err := s.PersistState(nil); err != nil {
		t.Fatalf("err: %s", err)
	}

	if sm, ok := s.(PersistentMeta); ok {
		newMeta = sm.StateSnapshotMeta()
		if newMeta.Serial != serial {
			t.Fatalf("serial changed after persisting with no changes: got %d, want %d", newMeta.Serial, serial)
		}
	}

	if sm, ok := s.(PersistentMeta); ok {
		newMeta = sm.StateSnapshotMeta()
	}

	// Change the serial
	current = current.DeepCopy()
	current.EnsureModule(addrs.RootModuleInstance).SetOutputValue(
		"serialCheck", cty.StringVal("true"), false,
	)
	if err := s.WriteState(current); err != nil {
		t.Fatalf("err: %s", err)
	}
	if err := s.PersistState(nil); err != nil {
		t.Fatalf("err: %s", err)
	}

	if sm, ok := s.(PersistentMeta); ok {
		oldMeta := newMeta
		newMeta = sm.StateSnapshotMeta()

		if newMeta.Serial <= serial {
			t.Fatalf("serial incorrect after persisting with changes: got %d, want > %d", newMeta.Serial, serial)
		}

		if newMeta.TerraformVersion != oldMeta.TerraformVersion {
			t.Fatalf("TFVersion changed from %s to %s", oldMeta.TerraformVersion, newMeta.TerraformVersion)
		}

		// verify that Lineage doesn't change along with Serial, or during copying.
		if newMeta.Lineage != oldMeta.Lineage {
			t.Fatalf("Lineage changed from %q to %q", oldMeta.Lineage, newMeta.Lineage)
		}
	}

	// Check that State() returns a copy by modifying the copy and comparing
	// to the current state.
	stateCopy := s.State()
	stateCopy.EnsureModule(addrs.RootModuleInstance.Child("another", addrs.NoKey))
	if reflect.DeepEqual(stateCopy, s.State()) {
		t.Fatal("State() should return a copy")
	}

	// our current expected state should also marshal identically to the persisted state
	if !statefile.StatesMarshalEqual(current, s.State()) {
		t.Fatalf("Persisted state altered unexpectedly.\n\ngot:\n%s\nwant:\n%s", spew.Sdump(s.State()), spew.Sdump(current))
	}
}

// TestFullInitialState is a state that should be snapshotted into a
// full state manager before passing it into TestFull.
func TestFullInitialState() *states.State {
	state := states.NewState()
	childMod := state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey))
	rAddr := addrs.Resource{
		Mode: addrs.ManagedResourceMode,
		Type: "null_resource",
		Name: "foo",
	}
	providerAddr := addrs.AbsProviderConfig{
		Provider: addrs.NewDefaultProvider(rAddr.ImpliedProvider()),
		Module:   addrs.RootModule,
	}
	childMod.SetResourceProvider(rAddr, providerAddr)

	state.RootModule().SetOutputValue("sensitive_output", cty.StringVal("it's a secret"), true)
	state.RootModule().SetOutputValue("nonsensitive_output", cty.StringVal("hello, world!"), false)

	return state
}
