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

package statemgr

import (
	"testing"

	"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"
)

func TestCheckValidImport(t *testing.T) {
	barState := states.BuildState(func(s *states.SyncState) {
		s.SetOutputValue(
			addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
			cty.StringVal("bar"), false,
		)
	})
	notBarState := states.BuildState(func(s *states.SyncState) {
		s.SetOutputValue(
			addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
			cty.StringVal("not bar"), false,
		)
	})
	emptyState := states.NewState()

	tests := map[string]struct {
		New      *statefile.File
		Existing *statefile.File
		WantErr  string
	}{
		"exact match": {
			New:      statefile.New(barState, "lineage", 1),
			Existing: statefile.New(barState, "lineage", 1),
			WantErr:  ``,
		},
		"overwrite unrelated empty state": {
			New:      statefile.New(barState, "lineage1", 1),
			Existing: statefile.New(emptyState, "lineage2", 1),
			WantErr:  ``,
		},
		"different state with same serial": {
			New:      statefile.New(barState, "lineage", 1),
			Existing: statefile.New(notBarState, "lineage", 1),
			WantErr:  `cannot overwrite existing state with serial 1 with a different state that has the same serial`,
		},
		"different state with newer serial": {
			New:      statefile.New(barState, "lineage", 2),
			Existing: statefile.New(notBarState, "lineage", 1),
			WantErr:  ``,
		},
		"different state with older serial": {
			New:      statefile.New(barState, "lineage", 1),
			Existing: statefile.New(notBarState, "lineage", 2),
			WantErr:  `cannot import state with serial 1 over newer state with serial 2`,
		},
		"different lineage with same serial": {
			New:      statefile.New(barState, "lineage1", 2),
			Existing: statefile.New(notBarState, "lineage2", 2),
			WantErr:  `cannot import state with lineage "lineage1" over unrelated state with lineage "lineage2"`,
		},
		"different lineage with different serial": {
			New:      statefile.New(barState, "lineage1", 3),
			Existing: statefile.New(notBarState, "lineage2", 2),
			WantErr:  `cannot import state with lineage "lineage1" over unrelated state with lineage "lineage2"`,
		},
		"new state is legacy": {
			New:      statefile.New(barState, "", 2),
			Existing: statefile.New(notBarState, "lineage", 2),
			WantErr:  ``,
		},
		"old state is legacy": {
			New:      statefile.New(barState, "lineage", 2),
			Existing: statefile.New(notBarState, "", 2),
			WantErr:  ``,
		},
		"both states are legacy": {
			New:      statefile.New(barState, "", 2),
			Existing: statefile.New(notBarState, "", 2),
			WantErr:  ``,
		},
	}

	for name, test := range tests {
		t.Run(name, func(t *testing.T) {
			gotErr := CheckValidImport(test.New, test.Existing)

			if test.WantErr == "" {
				if gotErr != nil {
					t.Errorf("unexpected error: %s", gotErr)
				}
			} else {
				if gotErr == nil {
					t.Errorf("succeeded, but want error: %s", test.WantErr)
				} else if got, want := gotErr.Error(), test.WantErr; got != want {
					t.Errorf("wrong error\ngot:  %s\nwant: %s", got, want)
				}
			}
		})
	}
}
