package command

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/depsfile"
	"github.com/hashicorp/terraform/internal/getproviders"
	"github.com/mitchellh/cli"
)

func TestProvidersLock(t *testing.T) {
	t.Run("noop", func(t *testing.T) {
		// in the most basic case, running providers lock in a directory with no configuration at all should succeed.
		// create an empty working directory
		td := t.TempDir()
		os.MkdirAll(td, 0755)
		defer testChdir(t, td)()

		ui := new(cli.MockUi)
		c := &ProvidersLockCommand{
			Meta: Meta{
				Ui: ui,
			},
		}
		code := c.Run([]string{})
		if code != 0 {
			t.Fatalf("wrong exit code; expected 0, got %d", code)
		}
	})

	// This test depends on the -fs-mirror argument, so we always know what results to expect
	t.Run("basic", func(t *testing.T) {
		testDirectory := "providers-lock/basic"
		expected := `# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.

provider "registry.terraform.io/hashicorp/test" {
  version = "1.0.0"
  hashes = [
    "h1:7MjN4eFisdTv4tlhXH5hL4QQd39Jy4baPhFxwAd/EFE=",
  ]
}
`
		runProviderLockGenericTest(t, testDirectory, expected)
	})

	// This test depends on the -fs-mirror argument, so we always know what results to expect
	t.Run("append", func(t *testing.T) {
		testDirectory := "providers-lock/append"
		expected := `# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.

provider "registry.terraform.io/hashicorp/test" {
  version = "1.0.0"
  hashes = [
    "h1:7MjN4eFisdTv4tlhXH5hL4QQd39Jy4baPhFxwAd/EFE=",
    "h1:invalid",
  ]
}
`
		runProviderLockGenericTest(t, testDirectory, expected)
	})
}

func runProviderLockGenericTest(t *testing.T, testDirectory, expected string) {
	td := t.TempDir()
	testCopyDir(t, testFixturePath(testDirectory), td)
	defer testChdir(t, td)()

	// Our fixture dir has a generic os_arch dir, which we need to customize
	// to the actual OS/arch where this test is running in order to get the
	// desired result.
	fixtMachineDir := filepath.Join(td, "fs-mirror/registry.terraform.io/hashicorp/test/1.0.0/os_arch")
	wantMachineDir := filepath.Join(td, "fs-mirror/registry.terraform.io/hashicorp/test/1.0.0/", fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH))
	err := os.Rename(fixtMachineDir, wantMachineDir)
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}

	p := testProvider()
	ui := new(cli.MockUi)
	c := &ProvidersLockCommand{
		Meta: Meta{
			Ui:               ui,
			testingOverrides: metaOverridesForProvider(p),
		},
	}

	args := []string{"-fs-mirror=fs-mirror"}
	code := c.Run(args)
	if code != 0 {
		t.Fatalf("wrong exit code; expected 0, got %d", code)
	}

	lockfile, err := os.ReadFile(".terraform.lock.hcl")
	if err != nil {
		t.Fatal("error reading lockfile")
	}

	if string(lockfile) != expected {
		t.Fatalf("wrong lockfile content")
	}
}

func TestProvidersLock_args(t *testing.T) {

	t.Run("mirror collision", func(t *testing.T) {
		ui := new(cli.MockUi)
		c := &ProvidersLockCommand{
			Meta: Meta{
				Ui: ui,
			},
		}

		// only one of these arguments can be used at a time
		args := []string{
			"-fs-mirror=/foo/",
			"-net-mirror=www.foo.com",
		}
		code := c.Run(args)

		if code != 1 {
			t.Fatalf("wrong exit code; expected 1, got %d", code)
		}
		output := ui.ErrorWriter.String()
		if !strings.Contains(output, "The -fs-mirror and -net-mirror command line options are mutually-exclusive.") {
			t.Fatalf("missing expected error message: %s", output)
		}
	})

	t.Run("invalid platform", func(t *testing.T) {
		ui := new(cli.MockUi)
		c := &ProvidersLockCommand{
			Meta: Meta{
				Ui: ui,
			},
		}

		// not a valid platform
		args := []string{"-platform=arbitrary_nonsense_that_isnt_valid"}
		code := c.Run(args)

		if code != 1 {
			t.Fatalf("wrong exit code; expected 1, got %d", code)
		}
		output := ui.ErrorWriter.String()
		if !strings.Contains(output, "must be two words separated by an underscore.") {
			t.Fatalf("missing expected error message: %s", output)
		}
	})

	t.Run("invalid provider argument", func(t *testing.T) {
		ui := new(cli.MockUi)
		c := &ProvidersLockCommand{
			Meta: Meta{
				Ui: ui,
			},
		}

		// There is no configuration, so it's not valid to use any provider argument
		args := []string{"hashicorp/random"}
		code := c.Run(args)

		if code != 1 {
			t.Fatalf("wrong exit code; expected 1, got %d", code)
		}
		output := ui.ErrorWriter.String()
		if !strings.Contains(output, "The provider registry.terraform.io/hashicorp/random is not required by the\ncurrent configuration.") {
			t.Fatalf("missing expected error message: %s", output)
		}
	})
}

func TestProvidersLockCalculateChangeType(t *testing.T) {
	provider := addrs.NewDefaultProvider("provider")
	v2 := getproviders.MustParseVersion("2.0.0")
	v2EqConstraints := getproviders.MustParseVersionConstraints("2.0.0")

	t.Run("oldLock == nil", func(t *testing.T) {
		platformLock := depsfile.NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
			"9r3i9a9QmASqMnQM",
			"K43RHM2klOoywtyW",
			"swJPXfuCNhJsTM5c",
		})

		if ct := providersLockCalculateChangeType(nil, platformLock); ct != providersLockChangeTypeNewProvider {
			t.Fatalf("output was %s but should be %s", ct, providersLockChangeTypeNewProvider)
		}
	})

	t.Run("oldLock == platformLock", func(t *testing.T) {
		platformLock := depsfile.NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
			"9r3i9a9QmASqMnQM",
			"K43RHM2klOoywtyW",
			"swJPXfuCNhJsTM5c",
		})

		oldLock := depsfile.NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
			"9r3i9a9QmASqMnQM",
			"K43RHM2klOoywtyW",
			"swJPXfuCNhJsTM5c",
		})

		if ct := providersLockCalculateChangeType(oldLock, platformLock); ct != providersLockChangeTypeNoChange {
			t.Fatalf("output was %s but should be %s", ct, providersLockChangeTypeNoChange)
		}
	})

	t.Run("oldLock > platformLock", func(t *testing.T) {
		platformLock := depsfile.NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
			"9r3i9a9QmASqMnQM",
			"K43RHM2klOoywtyW",
			"swJPXfuCNhJsTM5c",
		})

		oldLock := depsfile.NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
			"9r3i9a9QmASqMnQM",
			"1ZAChGWUMWn4zmIk",
			"K43RHM2klOoywtyW",
			"HWjRvIuWZ1LVatnc",
			"swJPXfuCNhJsTM5c",
			"KwhJK4p/U2dqbKhI",
		})

		if ct := providersLockCalculateChangeType(oldLock, platformLock); ct != providersLockChangeTypeNoChange {
			t.Fatalf("output was %s but should be %s", ct, providersLockChangeTypeNoChange)
		}
	})

	t.Run("oldLock < platformLock", func(t *testing.T) {
		platformLock := depsfile.NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
			"9r3i9a9QmASqMnQM",
			"1ZAChGWUMWn4zmIk",
			"K43RHM2klOoywtyW",
			"HWjRvIuWZ1LVatnc",
			"swJPXfuCNhJsTM5c",
			"KwhJK4p/U2dqbKhI",
		})

		oldLock := depsfile.NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
			"9r3i9a9QmASqMnQM",
			"K43RHM2klOoywtyW",
			"swJPXfuCNhJsTM5c",
		})

		if ct := providersLockCalculateChangeType(oldLock, platformLock); ct != providersLockChangeTypeNewHashes {
			t.Fatalf("output was %s but should be %s", ct, providersLockChangeTypeNoChange)
		}
	})
}
