// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1

package stackmigrate

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/hashicorp/terraform/internal/backend/local"
)

// DefaultDataDir is the default directory for storing local data.
const DefaultDataDir = ".terraform"

func TestMeta_Workspace_override(t *testing.T) {
	defer func(value string) {
		os.Setenv(WorkspaceNameEnvVar, value)
	}(os.Getenv(WorkspaceNameEnvVar))

	m := new(Meta)

	testCases := map[string]struct {
		workspace string
		err       error
	}{
		"": {
			"default",
			nil,
		},
		"development": {
			"development",
			nil,
		},
		"invalid name": {
			"",
			errInvalidWorkspaceNameEnvVar,
		},
	}

	for name, tc := range testCases {
		t.Run(name, func(t *testing.T) {
			os.Setenv(WorkspaceNameEnvVar, name)
			workspace, err := m.Workspace()
			if workspace != tc.workspace {
				t.Errorf("Unexpected workspace\n got: %s\nwant: %s\n", workspace, tc.workspace)
			}
			if err != tc.err {
				t.Errorf("Unexpected error\n got: %s\nwant: %s\n", err, tc.err)
			}
		})
	}
}

// If somehow an invalid workspace has been selected, the Meta.Workspace
// method should not return an error, to ensure that we don't break any
// existing workflows with invalid workspace names.
func TestMeta_Workspace_invalidSelected(t *testing.T) {
	td := t.TempDir()
	t.Chdir(td)

	// this is an invalid workspace name
	workspace := "test workspace"

	// create the workspace directories
	if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, workspace), 0755); err != nil {
		t.Fatal(err)
	}

	// create the workspace file to select it
	if err := os.MkdirAll(DefaultDataDir, 0755); err != nil {
		t.Fatal(err)
	}
	if err := os.WriteFile(filepath.Join(DefaultDataDir, local.DefaultWorkspaceFile), []byte(workspace), 0644); err != nil {
		t.Fatal(err)
	}

	m := new(Meta)

	// Normally, errors are returned when selecting an invalid workspace.
	ws, err := m.Workspace()
	if ws != "" {
		t.Errorf("Unexpected workspace\n got: %s\nwant: %s\n", ws, workspace)
	}
	if err == nil {
		t.Errorf("Expected error but got none")
	}

	// The Meta in the command package has a field `bypassWorkspaceNameValidityCheck` that allows
	// a selected workspace to be invalid in specific commands (i.e. enough to enable users to recover from an invalid value).
	// This can be implemented in Stacks when/if needed.
}
