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

package statemgr

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
	"testing"

	"github.com/go-test/deep"
	version "github.com/hashicorp/go-version"
	"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"
	tfversion "github.com/hashicorp/terraform/version"
)

func TestFilesystem(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()
	ls := testFilesystem(t)
	defer os.Remove(ls.readPath)
	TestFull(t, ls)
}

func TestFilesystemRace(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()
	ls := testFilesystem(t)
	defer os.Remove(ls.readPath)

	current := TestFullInitialState()

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			ls.WriteState(current)
		}()
	}
	wg.Wait()
}

func TestFilesystemLocks(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()
	s := testFilesystem(t)
	defer os.Remove(s.readPath)

	// lock first
	info := NewLockInfo()
	info.Operation = "test"
	lockID, err := s.Lock(info)
	if err != nil {
		t.Fatal(err)
	}

	out, err := exec.Command("go", "run", "testdata/lockstate.go", s.path).CombinedOutput()
	if err != nil {
		t.Fatal("unexpected lock failure", err, string(out))
	}

	if !strings.Contains(string(out), "lock failed") {
		t.Fatal("expected 'locked failed', got", string(out))
	}

	// check our lock info
	lockInfo, err := s.lockInfo()
	if err != nil {
		t.Fatal(err)
	}

	if lockInfo.Operation != "test" {
		t.Fatalf("invalid lock info %#v\n", lockInfo)
	}

	// a noop, since we unlock on exit
	if err := s.Unlock(lockID); err != nil {
		t.Fatal(err)
	}

	// local locks can re-lock
	lockID, err = s.Lock(info)
	if err != nil {
		t.Fatal(err)
	}

	if err := s.Unlock(lockID); err != nil {
		t.Fatal(err)
	}

	// we should not be able to unlock the same lock twice
	if err := s.Unlock(lockID); err == nil {
		t.Fatal("unlocking an unlocked state should fail")
	}

	// make sure lock info is gone
	lockInfoPath := s.lockInfoPath()
	if _, err := os.Stat(lockInfoPath); !os.IsNotExist(err) {
		t.Fatal("lock info not removed")
	}
}

// Verify that we can write to the state file, as Windows' mandatory locking
// will prevent writing to a handle different than the one that hold the lock.
func TestFilesystem_writeWhileLocked(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()
	s := testFilesystem(t)
	defer os.Remove(s.readPath)

	// lock first
	info := NewLockInfo()
	info.Operation = "test"
	lockID, err := s.Lock(info)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := s.Unlock(lockID); err != nil {
			t.Fatal(err)
		}
	}()

	if err := s.WriteState(TestFullInitialState()); err != nil {
		t.Fatal(err)
	}
}

func TestFilesystem_pathOut(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()
	f, err := ioutil.TempFile("", "tf")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	f.Close()
	defer os.Remove(f.Name())

	ls := testFilesystem(t)
	ls.path = f.Name()
	defer os.Remove(ls.path)

	TestFull(t, ls)
}

func TestFilesystem_backup(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()
	f, err := ioutil.TempFile("", "tf")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	f.Close()
	defer os.Remove(f.Name())

	ls := testFilesystem(t)
	backupPath := f.Name()
	ls.SetBackupPath(backupPath)

	TestFull(t, ls)

	// The backup functionality should've saved a copy of the original state
	// prior to all of the modifications that TestFull does.
	bfh, err := os.Open(backupPath)
	if err != nil {
		t.Fatal(err)
	}
	bf, err := statefile.Read(bfh)
	if err != nil {
		t.Fatal(err)
	}
	origState := TestFullInitialState()
	if !bf.State.Equal(origState) {
		for _, problem := range deep.Equal(origState, bf.State) {
			t.Error(problem)
		}
	}
}

// This test verifies a particularly tricky behavior where the input file
// is overridden and backups are enabled at the same time. This combination
// requires special care because we must ensure that when we create a backup
// it is of the original contents of the output file (which we're overwriting),
// not the contents of the input file (which is left unchanged).
func TestFilesystem_backupAndReadPath(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()

	workDir := t.TempDir()

	markerOutput := addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance)

	outState := states.BuildState(func(ss *states.SyncState) {
		ss.SetOutputValue(
			markerOutput,
			cty.StringVal("from-output-state"),
			false, // not sensitive
		)
	})
	outFile, err := os.Create(filepath.Join(workDir, "output.tfstate"))
	if err != nil {
		t.Fatalf("failed to create temporary outFile %s", err)
	}
	defer outFile.Close()
	err = statefile.Write(&statefile.File{
		Lineage:          "-",
		Serial:           0,
		TerraformVersion: version.Must(version.NewVersion("1.2.3")),
		State:            outState,
	}, outFile)
	if err != nil {
		t.Fatalf("failed to write initial outfile state to %s: %s", outFile.Name(), err)
	}

	inState := states.BuildState(func(ss *states.SyncState) {
		ss.SetOutputValue(
			markerOutput,
			cty.StringVal("from-input-state"),
			false, // not sensitive
		)
	})
	inFile, err := os.Create(filepath.Join(workDir, "input.tfstate"))
	if err != nil {
		t.Fatalf("failed to create temporary inFile %s", err)
	}
	defer inFile.Close()
	err = statefile.Write(&statefile.File{
		Lineage:          "-",
		Serial:           0,
		TerraformVersion: version.Must(version.NewVersion("1.2.3")),
		State:            inState,
	}, inFile)
	if err != nil {
		t.Fatalf("failed to write initial infile state to %s: %s", inFile.Name(), err)
	}

	backupPath := outFile.Name() + ".backup"

	ls := NewFilesystemBetweenPaths(inFile.Name(), outFile.Name())
	ls.SetBackupPath(backupPath)

	newState := states.BuildState(func(ss *states.SyncState) {
		ss.SetOutputValue(
			markerOutput,
			cty.StringVal("from-new-state"),
			false, // not sensitive
		)
	})
	err = ls.WriteState(newState)
	if err != nil {
		t.Fatalf("failed to write new state: %s", err)
	}

	// The backup functionality should've saved a copy of the original contents
	// of the _output_ file, even though the first snapshot was read from
	// the _input_ file.
	t.Run("backup file", func(t *testing.T) {
		bfh, err := os.Open(backupPath)
		if err != nil {
			t.Fatal(err)
		}
		bf, err := statefile.Read(bfh)
		if err != nil {
			t.Fatal(err)
		}
		os := bf.State.OutputValue(markerOutput)
		if got, want := os.Value, cty.StringVal("from-output-state"); !want.RawEquals(got) {
			t.Errorf("wrong marker value in backup state file\ngot:  %#v\nwant: %#v", got, want)
		}
	})
	t.Run("output file", func(t *testing.T) {
		ofh, err := os.Open(outFile.Name())
		if err != nil {
			t.Fatal(err)
		}
		of, err := statefile.Read(ofh)
		if err != nil {
			t.Fatal(err)
		}
		os := of.State.OutputValue(markerOutput)
		if got, want := os.Value, cty.StringVal("from-new-state"); !want.RawEquals(got) {
			t.Errorf("wrong marker value in backup state file\ngot:  %#v\nwant: %#v", got, want)
		}
	})
}

func TestFilesystem_nonExist(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()
	ls := NewFilesystem("ishouldntexist")
	if err := ls.RefreshState(); err != nil {
		t.Fatalf("err: %s", err)
	}

	if state := ls.State(); state != nil {
		t.Fatalf("bad: %#v", state)
	}
}

func TestFilesystem_lockUnlockWithoutWrite(t *testing.T) {
	info := NewLockInfo()
	info.Operation = "test"

	ls := testFilesystem(t)

	// Delete the just-created tempfile so that Lock recreates it
	os.Remove(ls.path)

	// Lock the state, and in doing so recreate the tempfile
	lockID, err := ls.Lock(info)
	if err != nil {
		t.Fatal(err)
	}

	if !ls.created {
		t.Fatal("should have marked state as created")
	}

	if err := ls.Unlock(lockID); err != nil {
		t.Fatal(err)
	}

	_, err = os.Stat(ls.path)
	if os.IsNotExist(err) {
		// Success! Unlocking the state successfully deleted the tempfile
		return
	} else if err != nil {
		t.Fatalf("unexpected error from os.Stat: %s", err)
	} else {
		os.Remove(ls.readPath)
		t.Fatal("should have removed path, but exists")
	}
}

func TestFilesystem_impl(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()
	var _ Reader = new(Filesystem)
	var _ Writer = new(Filesystem)
	var _ Persister = new(Filesystem)
	var _ Refresher = new(Filesystem)
	var _ OutputReader = new(Filesystem)
	var _ Locker = new(Filesystem)
}

func testFilesystem(t *testing.T) *Filesystem {
	f, err := ioutil.TempFile("", "tf")
	if err != nil {
		t.Fatalf("failed to create temporary file %s", err)
	}
	t.Logf("temporary state file at %s", f.Name())

	err = statefile.Write(&statefile.File{
		Lineage:          "test-lineage",
		Serial:           0,
		TerraformVersion: version.Must(version.NewVersion("1.2.3")),
		State:            TestFullInitialState(),
	}, f)
	if err != nil {
		t.Fatalf("failed to write initial state to %s: %s", f.Name(), err)
	}
	f.Close()

	ls := NewFilesystem(f.Name())
	if err := ls.RefreshState(); err != nil {
		t.Fatalf("initial refresh failed: %s", err)
	}

	return ls
}

// Make sure we can refresh while the state is locked
func TestFilesystem_refreshWhileLocked(t *testing.T) {
	defer testOverrideVersion(t, "1.2.3")()
	f, err := ioutil.TempFile("", "tf")
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	err = statefile.Write(&statefile.File{
		Lineage:          "test-lineage",
		Serial:           0,
		TerraformVersion: version.Must(version.NewVersion("1.2.3")),
		State:            TestFullInitialState(),
	}, f)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	f.Close()

	s := NewFilesystem(f.Name())
	defer os.Remove(s.path)

	// lock first
	info := NewLockInfo()
	info.Operation = "test"
	lockID, err := s.Lock(info)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := s.Unlock(lockID); err != nil {
			t.Fatal(err)
		}
	}()

	if err := s.RefreshState(); err != nil {
		t.Fatal(err)
	}

	readState := s.State()
	if readState == nil {
		t.Fatal("missing state")
	}
}

func TestFilesystem_GetRootOutputValues(t *testing.T) {
	fs := testFilesystem(t)

	outputs, err := fs.GetRootOutputValues()
	if err != nil {
		t.Errorf("Expected GetRootOutputValues to not return an error, but it returned %v", err)
	}

	if len(outputs) != 2 {
		t.Errorf("Expected %d outputs, but received %d", 2, len(outputs))
	}
}

func testOverrideVersion(t *testing.T, v string) func() {
	oldVersionStr := tfversion.Version
	oldPrereleaseStr := tfversion.Prerelease
	oldSemVer := tfversion.SemVer

	var newPrereleaseStr string
	if dash := strings.Index(v, "-"); dash != -1 {
		newPrereleaseStr = v[dash+1:]
		v = v[:dash]
	}

	newSemVer, err := version.NewVersion(v)
	if err != nil {
		t.Errorf("invalid override version %q: %s", v, err)
	}
	newVersionStr := newSemVer.String()

	tfversion.Version = newVersionStr
	tfversion.Prerelease = newPrereleaseStr
	tfversion.SemVer = newSemVer

	return func() { // reset function
		tfversion.Version = oldVersionStr
		tfversion.Prerelease = oldPrereleaseStr
		tfversion.SemVer = oldSemVer
	}
}
