package command

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs/configschema"
	"github.com/hashicorp/terraform/internal/plans"
	"github.com/hashicorp/terraform/internal/providers"
	"github.com/hashicorp/terraform/internal/states"
	"github.com/hashicorp/terraform/internal/states/statemgr"
	"github.com/hashicorp/terraform/internal/terraform"
	"github.com/hashicorp/terraform/version"
	"github.com/mitchellh/cli"
	"github.com/zclconf/go-cty/cty"
)

func TestShow_badArgs(t *testing.T) {
	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(testProvider()),
			View:             view,
		},
	}

	args := []string{
		"bad",
		"bad",
		"-no-color",
	}

	code := c.Run(args)
	output := done(t)

	if code != 1 {
		t.Fatalf("unexpected exit status %d; want 1\ngot: %s", code, output.Stdout())
	}
}

func TestShow_noArgsNoState(t *testing.T) {
	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(testProvider()),
			View:             view,
		},
	}

	code := c.Run([]string{})
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}

	got := output.Stdout()
	want := `No state.`
	if !strings.Contains(got, want) {
		t.Fatalf("unexpected output\ngot: %s\nwant: %s", got, want)
	}
}

func TestShow_noArgsWithState(t *testing.T) {
	// Get a temp cwd
	testCwd(t)
	// Create the default state
	testStateFileDefault(t, testState())

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(showFixtureProvider()),
			View:             view,
		},
	}

	code := c.Run([]string{})
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}

	got := output.Stdout()
	want := `# test_instance.foo:`
	if !strings.Contains(got, want) {
		t.Fatalf("unexpected output\ngot: %s\nwant: %s", got, want)
	}
}

func TestShow_argsWithState(t *testing.T) {
	// Create the default state
	statePath := testStateFile(t, testState())
	stateDir := filepath.Dir(statePath)
	defer os.RemoveAll(stateDir)
	defer testChdir(t, stateDir)()

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(showFixtureProvider()),
			View:             view,
		},
	}

	path := filepath.Base(statePath)
	args := []string{
		path,
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}
}

// https://github.com/hashicorp/terraform/issues/21462
func TestShow_argsWithStateAliasedProvider(t *testing.T) {
	// Create the default state with aliased resource
	testState := states.BuildState(func(s *states.SyncState) {
		s.SetResourceInstanceCurrent(
			addrs.Resource{
				Mode: addrs.ManagedResourceMode,
				Type: "test_instance",
				Name: "foo",
			}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
			&states.ResourceInstanceObjectSrc{
				// The weird whitespace here is reflective of how this would
				// get written out in a real state file, due to the indentation
				// of all of the containing wrapping objects and arrays.
				AttrsJSON:    []byte("{\n            \"id\": \"bar\"\n          }"),
				Status:       states.ObjectReady,
				Dependencies: []addrs.ConfigResource{},
			},
			addrs.RootModuleInstance.ProviderConfigAliased(addrs.NewDefaultProvider("test"), "alias"),
		)
	})

	statePath := testStateFile(t, testState)
	stateDir := filepath.Dir(statePath)
	defer os.RemoveAll(stateDir)
	defer testChdir(t, stateDir)()

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(showFixtureProvider()),
			View:             view,
		},
	}

	path := filepath.Base(statePath)
	args := []string{
		path,
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}

	got := output.Stdout()
	want := `# missing schema for provider \"test.alias\"`
	if strings.Contains(got, want) {
		t.Fatalf("unexpected output\ngot: %s", got)
	}
}

func TestShow_argsPlanFileDoesNotExist(t *testing.T) {
	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(testProvider()),
			View:             view,
		},
	}

	args := []string{
		"doesNotExist.tfplan",
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 1 {
		t.Fatalf("unexpected exit status %d; want 1\ngot: %s", code, output.Stdout())
	}

	got := output.Stderr()
	want := `Plan read error: open doesNotExist.tfplan:`
	if !strings.Contains(got, want) {
		t.Errorf("unexpected output\ngot: %s\nwant:\n%s", got, want)
	}
}

func TestShow_argsStatefileDoesNotExist(t *testing.T) {
	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(testProvider()),
			View:             view,
		},
	}

	args := []string{
		"doesNotExist.tfstate",
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 1 {
		t.Fatalf("unexpected exit status %d; want 1\ngot: %s", code, output.Stdout())
	}

	got := output.Stderr()
	want := `State read error: Error loading statefile:`
	if !strings.Contains(got, want) {
		t.Errorf("unexpected output\ngot: %s\nwant:\n%s", got, want)
	}
}

func TestShow_json_argsPlanFileDoesNotExist(t *testing.T) {
	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(testProvider()),
			View:             view,
		},
	}

	args := []string{
		"-json",
		"doesNotExist.tfplan",
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 1 {
		t.Fatalf("unexpected exit status %d; want 1\ngot: %s", code, output.Stdout())
	}

	got := output.Stderr()
	want := `Plan read error: open doesNotExist.tfplan:`
	if !strings.Contains(got, want) {
		t.Errorf("unexpected output\ngot: %s\nwant:\n%s", got, want)
	}
}

func TestShow_json_argsStatefileDoesNotExist(t *testing.T) {
	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(testProvider()),
			View:             view,
		},
	}

	args := []string{
		"-json",
		"doesNotExist.tfstate",
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 1 {
		t.Fatalf("unexpected exit status %d; want 1\ngot: %s", code, output.Stdout())
	}

	got := output.Stderr()
	want := `State read error: Error loading statefile:`
	if !strings.Contains(got, want) {
		t.Errorf("unexpected output\ngot: %s\nwant:\n%s", got, want)
	}
}

func TestShow_planNoop(t *testing.T) {
	planPath := testPlanFileNoop(t)

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(testProvider()),
			View:             view,
		},
	}

	args := []string{
		planPath,
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}

	got := output.Stdout()
	want := `No changes. Your infrastructure matches the configuration.`
	if !strings.Contains(got, want) {
		t.Errorf("unexpected output\ngot: %s\nwant:\n%s", got, want)
	}
}

func TestShow_planWithChanges(t *testing.T) {
	planPathWithChanges := showFixturePlanFile(t, plans.DeleteThenCreate)

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(showFixtureProvider()),
			View:             view,
		},
	}

	args := []string{
		planPathWithChanges,
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}

	got := output.Stdout()
	want := `test_instance.foo must be replaced`
	if !strings.Contains(got, want) {
		t.Fatalf("unexpected output\ngot: %s\nwant: %s", got, want)
	}
}

func TestShow_planWithForceReplaceChange(t *testing.T) {
	// The main goal of this test is to see that the "replace by request"
	// resource instance action reason can round-trip through a plan file and
	// be reflected correctly in the "terraform show" output, the same way
	// as it would appear in "terraform plan" output.

	_, snap := testModuleWithSnapshot(t, "show")
	plannedVal := cty.ObjectVal(map[string]cty.Value{
		"id":  cty.UnknownVal(cty.String),
		"ami": cty.StringVal("bar"),
	})
	priorValRaw, err := plans.NewDynamicValue(cty.NullVal(plannedVal.Type()), plannedVal.Type())
	if err != nil {
		t.Fatal(err)
	}
	plannedValRaw, err := plans.NewDynamicValue(plannedVal, plannedVal.Type())
	if err != nil {
		t.Fatal(err)
	}
	plan := testPlan(t)
	plan.Changes.SyncWrapper().AppendResourceInstanceChange(&plans.ResourceInstanceChangeSrc{
		Addr: addrs.Resource{
			Mode: addrs.ManagedResourceMode,
			Type: "test_instance",
			Name: "foo",
		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
		ProviderAddr: addrs.AbsProviderConfig{
			Provider: addrs.NewDefaultProvider("test"),
			Module:   addrs.RootModule,
		},
		ChangeSrc: plans.ChangeSrc{
			Action: plans.CreateThenDelete,
			Before: priorValRaw,
			After:  plannedValRaw,
		},
		ActionReason: plans.ResourceInstanceReplaceByRequest,
	})
	planFilePath := testPlanFile(
		t,
		snap,
		states.NewState(),
		plan,
	)

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(showFixtureProvider()),
			View:             view,
		},
	}

	args := []string{
		planFilePath,
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}

	got := output.Stdout()
	want := `test_instance.foo will be replaced, as requested`
	if !strings.Contains(got, want) {
		t.Fatalf("unexpected output\ngot: %s\nwant: %s", got, want)
	}

	want = `Plan: 1 to add, 0 to change, 1 to destroy.`
	if !strings.Contains(got, want) {
		t.Fatalf("unexpected output\ngot: %s\nwant: %s", got, want)
	}

}

func TestShow_plan_json(t *testing.T) {
	planPath := showFixturePlanFile(t, plans.Create)

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(showFixtureProvider()),
			View:             view,
		},
	}

	args := []string{
		"-json",
		planPath,
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}
}

func TestShow_state(t *testing.T) {
	originalState := testState()
	root := originalState.RootModule()
	root.SetOutputValue("test", cty.ObjectVal(map[string]cty.Value{
		"attr": cty.NullVal(cty.DynamicPseudoType),
		"null": cty.NullVal(cty.String),
		"list": cty.ListVal([]cty.Value{cty.NullVal(cty.Number)}),
	}), false)

	statePath := testStateFile(t, originalState)
	defer os.RemoveAll(filepath.Dir(statePath))

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(showFixtureProvider()),
			View:             view,
		},
	}

	args := []string{
		statePath,
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}
}

func TestShow_json_output(t *testing.T) {
	fixtureDir := "testdata/show-json"
	testDirs, err := ioutil.ReadDir(fixtureDir)
	if err != nil {
		t.Fatal(err)
	}

	for _, entry := range testDirs {
		if !entry.IsDir() {
			continue
		}

		t.Run(entry.Name(), func(t *testing.T) {
			td := t.TempDir()
			inputDir := filepath.Join(fixtureDir, entry.Name())
			testCopyDir(t, inputDir, td)
			defer testChdir(t, td)()

			expectError := strings.Contains(entry.Name(), "error")

			providerSource, close := newMockProviderSource(t, map[string][]string{
				"test":            {"1.2.3"},
				"hashicorp2/test": {"1.2.3"},
			})
			defer close()

			p := showFixtureProvider()

			// init
			ui := new(cli.MockUi)
			ic := &InitCommand{
				Meta: Meta{
					testingOverrides: metaOverridesForProvider(p),
					Ui:               ui,
					ProviderSource:   providerSource,
				},
			}
			if code := ic.Run([]string{}); code != 0 {
				if expectError {
					// this should error, but not panic.
					return
				}
				t.Fatalf("init failed\n%s", ui.ErrorWriter)
			}

			// plan
			planView, planDone := testView(t)
			pc := &PlanCommand{
				Meta: Meta{
					testingOverrides: metaOverridesForProvider(p),
					View:             planView,
					ProviderSource:   providerSource,
				},
			}

			args := []string{
				"-out=terraform.plan",
			}

			code := pc.Run(args)
			planOutput := planDone(t)

			if code != 0 {
				t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, planOutput.Stderr())
			}

			// show
			showView, showDone := testView(t)
			sc := &ShowCommand{
				Meta: Meta{
					testingOverrides: metaOverridesForProvider(p),
					View:             showView,
					ProviderSource:   providerSource,
				},
			}

			args = []string{
				"-json",
				"terraform.plan",
			}
			defer os.Remove("terraform.plan")
			code = sc.Run(args)
			showOutput := showDone(t)

			if code != 0 {
				t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, showOutput.Stderr())
			}

			// compare view output to wanted output
			var got, want plan

			gotString := showOutput.Stdout()
			json.Unmarshal([]byte(gotString), &got)

			wantFile, err := os.Open("output.json")
			if err != nil {
				t.Fatalf("unexpected err: %s", err)
			}
			defer wantFile.Close()
			byteValue, err := ioutil.ReadAll(wantFile)
			if err != nil {
				t.Fatalf("unexpected err: %s", err)
			}
			json.Unmarshal([]byte(byteValue), &want)

			// Disregard format version to reduce needless test fixture churn
			want.FormatVersion = got.FormatVersion

			if !cmp.Equal(got, want) {
				t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, want))
			}
		})
	}
}

func TestShow_json_output_sensitive(t *testing.T) {
	td := t.TempDir()
	inputDir := "testdata/show-json-sensitive"
	testCopyDir(t, inputDir, td)
	defer testChdir(t, td)()

	providerSource, close := newMockProviderSource(t, map[string][]string{"test": {"1.2.3"}})
	defer close()

	p := showFixtureSensitiveProvider()

	// init
	ui := new(cli.MockUi)
	ic := &InitCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(p),
			Ui:               ui,
			ProviderSource:   providerSource,
		},
	}
	if code := ic.Run([]string{}); code != 0 {
		t.Fatalf("init failed\n%s", ui.ErrorWriter)
	}

	// plan
	planView, planDone := testView(t)
	pc := &PlanCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(p),
			View:             planView,
			ProviderSource:   providerSource,
		},
	}

	args := []string{
		"-out=terraform.plan",
	}
	code := pc.Run(args)
	planOutput := planDone(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, planOutput.Stderr())
	}

	// show
	showView, showDone := testView(t)
	sc := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(p),
			View:             showView,
			ProviderSource:   providerSource,
		},
	}

	args = []string{
		"-json",
		"terraform.plan",
	}
	defer os.Remove("terraform.plan")
	code = sc.Run(args)
	showOutput := showDone(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, showOutput.Stderr())
	}

	// compare ui output to wanted output
	var got, want plan

	gotString := showOutput.Stdout()
	json.Unmarshal([]byte(gotString), &got)

	wantFile, err := os.Open("output.json")
	if err != nil {
		t.Fatalf("unexpected err: %s", err)
	}
	defer wantFile.Close()
	byteValue, err := ioutil.ReadAll(wantFile)
	if err != nil {
		t.Fatalf("unexpected err: %s", err)
	}
	json.Unmarshal([]byte(byteValue), &want)

	// Disregard format version to reduce needless test fixture churn
	want.FormatVersion = got.FormatVersion

	if !cmp.Equal(got, want) {
		t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, want))
	}
}

// Failing conditions are only present in JSON output for refresh-only plans,
// so we test that separately here.
func TestShow_json_output_conditions_refresh_only(t *testing.T) {
	td := t.TempDir()
	inputDir := "testdata/show-json/conditions"
	testCopyDir(t, inputDir, td)
	defer testChdir(t, td)()

	providerSource, close := newMockProviderSource(t, map[string][]string{"test": {"1.2.3"}})
	defer close()

	p := showFixtureSensitiveProvider()

	// init
	ui := new(cli.MockUi)
	ic := &InitCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(p),
			Ui:               ui,
			ProviderSource:   providerSource,
		},
	}
	if code := ic.Run([]string{}); code != 0 {
		t.Fatalf("init failed\n%s", ui.ErrorWriter)
	}

	// plan
	planView, planDone := testView(t)
	pc := &PlanCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(p),
			View:             planView,
			ProviderSource:   providerSource,
		},
	}

	args := []string{
		"-refresh-only",
		"-out=terraform.plan",
		"-var=ami=bad-ami",
		"-state=for-refresh.tfstate",
	}
	code := pc.Run(args)
	planOutput := planDone(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, planOutput.Stderr())
	}

	// show
	showView, showDone := testView(t)
	sc := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(p),
			View:             showView,
			ProviderSource:   providerSource,
		},
	}

	args = []string{
		"-json",
		"terraform.plan",
	}
	defer os.Remove("terraform.plan")
	code = sc.Run(args)
	showOutput := showDone(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, showOutput.Stderr())
	}

	// compare JSON output to wanted output
	var got, want plan

	gotString := showOutput.Stdout()
	json.Unmarshal([]byte(gotString), &got)

	wantFile, err := os.Open("output-refresh-only.json")
	if err != nil {
		t.Fatalf("unexpected err: %s", err)
	}
	defer wantFile.Close()
	byteValue, err := ioutil.ReadAll(wantFile)
	if err != nil {
		t.Fatalf("unexpected err: %s", err)
	}
	json.Unmarshal([]byte(byteValue), &want)

	// Disregard format version to reduce needless test fixture churn
	want.FormatVersion = got.FormatVersion

	if !cmp.Equal(got, want) {
		t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, want))
	}
}

// similar test as above, without the plan
func TestShow_json_output_state(t *testing.T) {
	fixtureDir := "testdata/show-json-state"
	testDirs, err := ioutil.ReadDir(fixtureDir)
	if err != nil {
		t.Fatal(err)
	}

	for _, entry := range testDirs {
		if !entry.IsDir() {
			continue
		}

		t.Run(entry.Name(), func(t *testing.T) {
			td := t.TempDir()
			inputDir := filepath.Join(fixtureDir, entry.Name())
			testCopyDir(t, inputDir, td)
			defer testChdir(t, td)()

			providerSource, close := newMockProviderSource(t, map[string][]string{
				"test": {"1.2.3"},
			})
			defer close()

			p := showFixtureProvider()

			// init
			ui := new(cli.MockUi)
			ic := &InitCommand{
				Meta: Meta{
					testingOverrides: metaOverridesForProvider(p),
					Ui:               ui,
					ProviderSource:   providerSource,
				},
			}
			if code := ic.Run([]string{}); code != 0 {
				t.Fatalf("init failed\n%s", ui.ErrorWriter)
			}

			// show
			showView, showDone := testView(t)
			sc := &ShowCommand{
				Meta: Meta{
					testingOverrides: metaOverridesForProvider(p),
					View:             showView,
					ProviderSource:   providerSource,
				},
			}

			code := sc.Run([]string{"-json"})
			showOutput := showDone(t)

			if code != 0 {
				t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, showOutput.Stderr())
			}

			// compare ui output to wanted output
			type state struct {
				FormatVersion    string                 `json:"format_version,omitempty"`
				TerraformVersion string                 `json:"terraform_version"`
				Values           map[string]interface{} `json:"values,omitempty"`
				SensitiveValues  map[string]bool        `json:"sensitive_values,omitempty"`
			}
			var got, want state

			gotString := showOutput.Stdout()
			json.Unmarshal([]byte(gotString), &got)

			wantFile, err := os.Open("output.json")
			if err != nil {
				t.Fatalf("unexpected error: %s", err)
			}
			defer wantFile.Close()
			byteValue, err := ioutil.ReadAll(wantFile)
			if err != nil {
				t.Fatalf("unexpected err: %s", err)
			}
			json.Unmarshal([]byte(byteValue), &want)

			if !cmp.Equal(got, want) {
				t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, want))
			}
		})
	}
}

func TestShow_planWithNonDefaultStateLineage(t *testing.T) {
	// Create a temporary working directory that is empty
	td := t.TempDir()
	testCopyDir(t, testFixturePath("show"), td)
	defer testChdir(t, td)()

	// Write default state file with a testing lineage ("fake-for-testing")
	testStateFileDefault(t, testState())

	// Create a plan with a different lineage, which we should still be able
	// to show
	_, snap := testModuleWithSnapshot(t, "show")
	state := testState()
	plan := testPlan(t)
	stateMeta := statemgr.SnapshotMeta{
		Lineage:          "fake-for-plan",
		Serial:           1,
		TerraformVersion: version.SemVer,
	}
	planPath := testPlanFileMatchState(t, snap, state, plan, stateMeta)

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(testProvider()),
			View:             view,
		},
	}

	args := []string{
		planPath,
		"-no-color",
	}
	code := c.Run(args)
	output := done(t)

	if code != 0 {
		t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, output.Stderr())
	}

	got := output.Stdout()
	want := `No changes. Your infrastructure matches the configuration.`
	if !strings.Contains(got, want) {
		t.Fatalf("unexpected output\ngot: %s\nwant: %s", got, want)
	}
}

func TestShow_corruptStatefile(t *testing.T) {
	td := t.TempDir()
	inputDir := "testdata/show-corrupt-statefile"
	testCopyDir(t, inputDir, td)
	defer testChdir(t, td)()

	view, done := testView(t)
	c := &ShowCommand{
		Meta: Meta{
			testingOverrides: metaOverridesForProvider(testProvider()),
			View:             view,
		},
	}

	code := c.Run([]string{})
	output := done(t)

	if code != 1 {
		t.Fatalf("unexpected exit status %d; want 1\ngot: %s", code, output.Stdout())
	}

	got := output.Stderr()
	want := `Unsupported state file format`
	if !strings.Contains(got, want) {
		t.Errorf("unexpected output\ngot: %s\nwant:\n%s", got, want)
	}
}

// showFixtureSchema returns a schema suitable for processing the configuration
// in testdata/show. This schema should be assigned to a mock provider
// named "test".
func showFixtureSchema() *providers.GetProviderSchemaResponse {
	return &providers.GetProviderSchemaResponse{
		Provider: providers.Schema{
			Block: &configschema.Block{
				Attributes: map[string]*configschema.Attribute{
					"region": {Type: cty.String, Optional: true},
				},
			},
		},
		ResourceTypes: map[string]providers.Schema{
			"test_instance": {
				Block: &configschema.Block{
					Attributes: map[string]*configschema.Attribute{
						"id":  {Type: cty.String, Optional: true, Computed: true},
						"ami": {Type: cty.String, Optional: true},
					},
				},
			},
		},
	}
}

// showFixtureSensitiveSchema returns a schema suitable for processing the configuration
// in testdata/show. This schema should be assigned to a mock provider
// named "test". It includes a sensitive attribute.
func showFixtureSensitiveSchema() *providers.GetProviderSchemaResponse {
	return &providers.GetProviderSchemaResponse{
		Provider: providers.Schema{
			Block: &configschema.Block{
				Attributes: map[string]*configschema.Attribute{
					"region": {Type: cty.String, Optional: true},
				},
			},
		},
		ResourceTypes: map[string]providers.Schema{
			"test_instance": {
				Block: &configschema.Block{
					Attributes: map[string]*configschema.Attribute{
						"id":       {Type: cty.String, Optional: true, Computed: true},
						"ami":      {Type: cty.String, Optional: true},
						"password": {Type: cty.String, Optional: true, Sensitive: true},
					},
				},
			},
		},
	}
}

// showFixtureProvider returns a mock provider that is configured for basic
// operation with the configuration in testdata/show. This mock has
// GetSchemaResponse, PlanResourceChangeFn, and ApplyResourceChangeFn populated,
// with the plan/apply steps just passing through the data determined by
// Terraform Core.
func showFixtureProvider() *terraform.MockProvider {
	p := testProvider()
	p.GetProviderSchemaResponse = showFixtureSchema()
	p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
		idVal := req.PriorState.GetAttr("id")
		amiVal := req.PriorState.GetAttr("ami")
		if amiVal.RawEquals(cty.StringVal("refresh-me")) {
			amiVal = cty.StringVal("refreshed")
		}
		return providers.ReadResourceResponse{
			NewState: cty.ObjectVal(map[string]cty.Value{
				"id":  idVal,
				"ami": amiVal,
			}),
			Private: req.Private,
		}
	}
	p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) (resp providers.PlanResourceChangeResponse) {
		// this is a destroy plan,
		if req.ProposedNewState.IsNull() {
			resp.PlannedState = req.ProposedNewState
			resp.PlannedPrivate = req.PriorPrivate
			return resp
		}

		idVal := req.ProposedNewState.GetAttr("id")
		amiVal := req.ProposedNewState.GetAttr("ami")
		if idVal.IsNull() {
			idVal = cty.UnknownVal(cty.String)
		}
		var reqRep []cty.Path
		if amiVal.RawEquals(cty.StringVal("force-replace")) {
			reqRep = append(reqRep, cty.GetAttrPath("ami"))
		}
		return providers.PlanResourceChangeResponse{
			PlannedState: cty.ObjectVal(map[string]cty.Value{
				"id":  idVal,
				"ami": amiVal,
			}),
			RequiresReplace: reqRep,
		}
	}
	p.ApplyResourceChangeFn = func(req providers.ApplyResourceChangeRequest) providers.ApplyResourceChangeResponse {
		idVal := req.PlannedState.GetAttr("id")
		amiVal := req.PlannedState.GetAttr("ami")
		if !idVal.IsKnown() {
			idVal = cty.StringVal("placeholder")
		}
		return providers.ApplyResourceChangeResponse{
			NewState: cty.ObjectVal(map[string]cty.Value{
				"id":  idVal,
				"ami": amiVal,
			}),
		}
	}
	return p
}

// showFixtureSensitiveProvider returns a mock provider that is configured for basic
// operation with the configuration in testdata/show. This mock has
// GetSchemaResponse, PlanResourceChangeFn, and ApplyResourceChangeFn populated,
// with the plan/apply steps just passing through the data determined by
// Terraform Core. It also has a sensitive attribute in the provider schema.
func showFixtureSensitiveProvider() *terraform.MockProvider {
	p := testProvider()
	p.GetProviderSchemaResponse = showFixtureSensitiveSchema()
	p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) providers.PlanResourceChangeResponse {
		idVal := req.ProposedNewState.GetAttr("id")
		if idVal.IsNull() {
			idVal = cty.UnknownVal(cty.String)
		}
		return providers.PlanResourceChangeResponse{
			PlannedState: cty.ObjectVal(map[string]cty.Value{
				"id":       idVal,
				"ami":      req.ProposedNewState.GetAttr("ami"),
				"password": req.ProposedNewState.GetAttr("password"),
			}),
		}
	}
	p.ApplyResourceChangeFn = func(req providers.ApplyResourceChangeRequest) providers.ApplyResourceChangeResponse {
		idVal := req.PlannedState.GetAttr("id")
		if !idVal.IsKnown() {
			idVal = cty.StringVal("placeholder")
		}
		return providers.ApplyResourceChangeResponse{
			NewState: cty.ObjectVal(map[string]cty.Value{
				"id":       idVal,
				"ami":      req.PlannedState.GetAttr("ami"),
				"password": req.PlannedState.GetAttr("password"),
			}),
		}
	}
	return p
}

// showFixturePlanFile creates a plan file at a temporary location containing a
// single change to create or update the test_instance.foo that is included in the "show"
// test fixture, returning the location of that plan file.
// `action` is the planned change you would like to elicit
func showFixturePlanFile(t *testing.T, action plans.Action) string {
	_, snap := testModuleWithSnapshot(t, "show")
	plannedVal := cty.ObjectVal(map[string]cty.Value{
		"id":  cty.UnknownVal(cty.String),
		"ami": cty.StringVal("bar"),
	})
	priorValRaw, err := plans.NewDynamicValue(cty.NullVal(plannedVal.Type()), plannedVal.Type())
	if err != nil {
		t.Fatal(err)
	}
	plannedValRaw, err := plans.NewDynamicValue(plannedVal, plannedVal.Type())
	if err != nil {
		t.Fatal(err)
	}
	plan := testPlan(t)
	plan.Changes.SyncWrapper().AppendResourceInstanceChange(&plans.ResourceInstanceChangeSrc{
		Addr: addrs.Resource{
			Mode: addrs.ManagedResourceMode,
			Type: "test_instance",
			Name: "foo",
		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
		ProviderAddr: addrs.AbsProviderConfig{
			Provider: addrs.NewDefaultProvider("test"),
			Module:   addrs.RootModule,
		},
		ChangeSrc: plans.ChangeSrc{
			Action: action,
			Before: priorValRaw,
			After:  plannedValRaw,
		},
	})
	return testPlanFile(
		t,
		snap,
		states.NewState(),
		plan,
	)
}

// this simplified plan struct allows us to preserve field order when marshaling
// the command output. NOTE: we are leaving "terraform_version" out of this test
// to avoid needing to constantly update the expected output; as a potential
// TODO we could write a jsonplan compare function.
type plan struct {
	FormatVersion   string                 `json:"format_version,omitempty"`
	Variables       map[string]interface{} `json:"variables,omitempty"`
	PlannedValues   map[string]interface{} `json:"planned_values,omitempty"`
	ResourceDrift   []interface{}          `json:"resource_drift,omitempty"`
	ResourceChanges []interface{}          `json:"resource_changes,omitempty"`
	OutputChanges   map[string]interface{} `json:"output_changes,omitempty"`
	PriorState      priorState             `json:"prior_state,omitempty"`
	Config          map[string]interface{} `json:"configuration,omitempty"`
}

type priorState struct {
	FormatVersion   string                 `json:"format_version,omitempty"`
	Values          map[string]interface{} `json:"values,omitempty"`
	SensitiveValues map[string]bool        `json:"sensitive_values,omitempty"`
}
