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

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