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

package terraform

import (
	"testing"

	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/hcl/v2/hcltest"
	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs"
	"github.com/hashicorp/terraform/internal/lang"
)

func TestNodeRootVariableExecute(t *testing.T) {
	t.Run("type conversion", func(t *testing.T) {
		ctx := new(MockEvalContext)

		n := &NodeRootVariable{
			Addr: addrs.InputVariable{Name: "foo"},
			Config: &configs.Variable{
				Name:           "foo",
				Type:           cty.String,
				ConstraintType: cty.String,
			},
			RawValue: &InputValue{
				Value:      cty.True,
				SourceType: ValueFromUnknown,
			},
		}

		diags := n.Execute(ctx, walkApply)
		if diags.HasErrors() {
			t.Fatalf("unexpected error: %s", diags.Err())
		}

		if !ctx.SetRootModuleArgumentCalled {
			t.Fatalf("ctx.SetRootModuleArgument wasn't called")
		}
		if got, want := ctx.SetRootModuleArgumentAddr.String(), "var.foo"; got != want {
			t.Errorf("wrong address for ctx.SetRootModuleArgument\ngot:  %s\nwant: %s", got, want)
		}
		if got, want := ctx.SetRootModuleArgumentValue, cty.StringVal("true"); !want.RawEquals(got) {
			// NOTE: The given value was cty.Bool but the type constraint was
			// cty.String, so it was NodeRootVariable's responsibility to convert
			// as part of preparing the "final value".
			t.Errorf("wrong value for ctx.SetRootModuleArgument\ngot:  %#v\nwant: %#v", got, want)
		}
	})
	t.Run("validation", func(t *testing.T) {
		ctx := new(MockEvalContext)

		// The variable validation function gets called with Terraform's
		// built-in functions available, so we need a minimal scope just for
		// it to get the functions from.
		ctx.EvaluationScopeScope = &lang.Scope{}

		// We need to reimplement a _little_ bit of EvalContextBuiltin logic
		// here to get a similar effect with EvalContextMock just to get the
		// value to flow through here in a realistic way that'll make this test
		// useful.
		var finalVal cty.Value
		ctx.SetRootModuleArgumentFunc = func(addr addrs.InputVariable, v cty.Value) {
			if addr.Name == "foo" {
				t.Logf("set %s to %#v", addr.String(), v)
				finalVal = v
			}
		}
		ctx.GetVariableValueFunc = func(addr addrs.AbsInputVariableInstance) cty.Value {
			if addr.String() != "var.foo" {
				return cty.NilVal
			}
			t.Logf("reading final val for %s (%#v)", addr.String(), finalVal)
			return finalVal
		}

		n := &NodeRootVariable{
			Addr: addrs.InputVariable{Name: "foo"},
			Config: &configs.Variable{
				Name:           "foo",
				Type:           cty.Number,
				ConstraintType: cty.Number,
				Validations: []*configs.CheckRule{
					{
						Condition: fakeHCLExpressionFunc(func(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
							// This returns true only if the given variable value
							// is exactly cty.Number, which allows us to verify
							// that we were given the value _after_ type
							// conversion.
							// This had previously not been handled correctly,
							// as reported in:
							//     https://github.com/hashicorp/terraform/issues/29899
							vars := ctx.Variables["var"]
							if vars == cty.NilVal || !vars.Type().IsObjectType() || !vars.Type().HasAttribute("foo") {
								t.Logf("var.foo isn't available")
								return cty.False, nil
							}
							val := vars.GetAttr("foo")
							if val == cty.NilVal || val.Type() != cty.Number {
								t.Logf("var.foo is %#v; want a number", val)
								return cty.False, nil
							}
							return cty.True, nil
						}),
						ErrorMessage: hcltest.MockExprLiteral(cty.StringVal("Must be a number.")),
					},
				},
			},
			RawValue: &InputValue{
				// Note: This is a string, but the variable's type constraint
				// is number so it should be converted before use.
				Value:      cty.StringVal("5"),
				SourceType: ValueFromUnknown,
			},
		}

		diags := n.Execute(ctx, walkApply)
		if diags.HasErrors() {
			t.Fatalf("unexpected error: %s", diags.Err())
		}

		if !ctx.SetRootModuleArgumentCalled {
			t.Fatalf("ctx.SetRootModuleArgument wasn't called")
		}
		if got, want := ctx.SetRootModuleArgumentAddr.String(), "var.foo"; got != want {
			t.Errorf("wrong address for ctx.SetRootModuleArgument\ngot:  %s\nwant: %s", got, want)
		}
		if got, want := ctx.SetRootModuleArgumentValue, cty.NumberIntVal(5); !want.RawEquals(got) {
			// NOTE: The given value was cty.Bool but the type constraint was
			// cty.String, so it was NodeRootVariable's responsibility to convert
			// as part of preparing the "final value".
			t.Errorf("wrong value for ctx.SetRootModuleArgument\ngot:  %#v\nwant: %#v", got, want)
		}
	})
}

// fakeHCLExpressionFunc is a fake implementation of hcl.Expression that just
// directly produces a value with direct Go code.
//
// An expression of this type has no references and so it cannot access any
// variables from the EvalContext unless something else arranges for them
// to be guaranteed available. For example, custom variable validations just
// unconditionally have access to the variable they are validating regardless
// of references.
type fakeHCLExpressionFunc func(*hcl.EvalContext) (cty.Value, hcl.Diagnostics)

var _ hcl.Expression = fakeHCLExpressionFunc(nil)

func (f fakeHCLExpressionFunc) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
	return f(ctx)
}

func (f fakeHCLExpressionFunc) Variables() []hcl.Traversal {
	return nil
}

func (f fakeHCLExpressionFunc) Range() hcl.Range {
	return hcl.Range{
		Filename: "fake",
		Start:    hcl.InitialPos,
		End:      hcl.InitialPos,
	}
}

func (f fakeHCLExpressionFunc) StartRange() hcl.Range {
	return f.Range()
}
