func testResourceConfig(
	t *testing.T, c map[string]interface{}) *ResourceConfig {
	raw, err := config.NewRawConfig(c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	return NewResourceConfig(raw)
}
// interpolateForce is a temporary thing. We want to get rid of interpolate
// above and likewise this, but it can only be done after the f-ast-graph
// refactor is complete.
func (c *ResourceConfig) interpolateForce() {
	if c.raw == nil {
		var err error
		c.raw, err = config.NewRawConfig(make(map[string]interface{}))
		if err != nil {
			panic(err)
		}
	}

	c.ComputedKeys = c.raw.UnknownKeys()
	c.Raw = c.raw.Raw
	c.Config = c.raw.Config()
}
func testConfigInterpolate(
	t *testing.T,
	raw map[string]interface{},
	vs map[string]ast.Variable) *terraform.ResourceConfig {
	rc, err := config.NewRawConfig(raw)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if len(vs) > 0 {
		if err := rc.Interpolate(vs); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	return terraform.NewResourceConfig(rc)
}
func TestProviderValidateResource(t *testing.T) {
	cases := []struct {
		P      *Provider
		Type   string
		Config map[string]interface{}
		Err    bool
	}{
		{
			P:      &Provider{},
			Type:   "foo",
			Config: nil,
			Err:    true,
		},

		{
			P: &Provider{
				ResourcesMap: map[string]*Resource{
					"foo": &Resource{},
				},
			},
			Type:   "foo",
			Config: nil,
			Err:    false,
		},
	}

	for i, tc := range cases {
		c, err := config.NewRawConfig(tc.Config)
		if err != nil {
			t.Fatalf("err: %s", err)
		}

		_, es := tc.P.ValidateResource(tc.Type, terraform.NewResourceConfig(c))
		if (len(es) > 0) != tc.Err {
			t.Fatalf("%d: %#v", i, es)
		}
	}
}
func (n *EvalBuildProviderConfig) Eval(ctx EvalContext) (interface{}, error) {
	cfg := *n.Config

	// If we have a configuration set, then merge that in
	if input := ctx.ProviderInput(n.Provider); input != nil {
		rc, err := config.NewRawConfig(input)
		if err != nil {
			return nil, err
		}

		merged := cfg.raw.Merge(rc)
		cfg = NewResourceConfig(merged)
	}

	// Get the parent configuration if there is one
	if parent := ctx.ParentProviderConfig(n.Provider); parent != nil {
		merged := cfg.raw.Merge(parent.raw)
		cfg = NewResourceConfig(merged)
	}

	*n.Output = cfg
	return nil, nil
}
// GraphNodeFlattenable impl.
func (n *graphNodeModuleExpanded) FlattenGraph() *Graph {
	graph := n.Subgraph()
	input := n.Original.Module.RawConfig

	// Go over each vertex and do some modifications to the graph for
	// flattening. We have to skip some nodes (graphNodeModuleSkippable)
	// as well as setup the variable values.
	for _, v := range graph.Vertices() {
		if sn, ok := v.(graphNodeModuleSkippable); ok && sn.FlattenSkip() {
			graph.Remove(v)
			continue
		}

		// If this is a variable, then look it up in the raw configuration.
		// If it exists in the raw configuration, set the value of it.
		if vn, ok := v.(*GraphNodeConfigVariable); ok && input != nil {
			key := vn.VariableName()
			if v, ok := input.Raw[key]; ok {
				config, err := config.NewRawConfig(map[string]interface{}{
					key: v,
				})
				if err != nil {
					// This shouldn't happen because it is already in
					// a RawConfig above meaning it worked once before.
					panic(err)
				}

				// Set the variable value so it is interpolated properly.
				// Also set the module so we set the value on it properly.
				vn.Module = graph.Path[len(graph.Path)-1]
				vn.Value = config
			}
		}
	}

	return graph
}
func TestEvalInterpolate(t *testing.T) {
	config, err := config.NewRawConfig(map[string]interface{}{})
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	var actual *ResourceConfig
	n := &EvalInterpolate{Config: config, Output: &actual}
	result := testResourceConfig(t, map[string]interface{}{})
	ctx := &MockEvalContext{InterpolateConfigResult: result}
	if _, err := n.Eval(ctx); err != nil {
		t.Fatalf("err: %s", err)
	}
	if actual != result {
		t.Fatalf("bad: %#v", actual)
	}

	if !ctx.InterpolateCalled {
		t.Fatal("should be called")
	}
	if !reflect.DeepEqual(ctx.InterpolateConfig, config) {
		t.Fatalf("bad: %#v", ctx.InterpolateConfig)
	}
}
func TestProviderConfigure(t *testing.T) {
	cases := []struct {
		P      *Provider
		Config map[string]interface{}
		Err    bool
	}{
		{
			P:      &Provider{},
			Config: nil,
			Err:    false,
		},

		{
			P: &Provider{
				Schema: map[string]*Schema{
					"foo": &Schema{
						Type:     TypeInt,
						Optional: true,
					},
				},

				ConfigureFunc: func(d *ResourceData) (interface{}, error) {
					if d.Get("foo").(int) == 42 {
						return nil, nil
					}

					return nil, fmt.Errorf("nope")
				},
			},
			Config: map[string]interface{}{
				"foo": 42,
			},
			Err: false,
		},

		{
			P: &Provider{
				Schema: map[string]*Schema{
					"foo": &Schema{
						Type:     TypeInt,
						Optional: true,
					},
				},

				ConfigureFunc: func(d *ResourceData) (interface{}, error) {
					if d.Get("foo").(int) == 42 {
						return nil, nil
					}

					return nil, fmt.Errorf("nope")
				},
			},
			Config: map[string]interface{}{
				"foo": 52,
			},
			Err: true,
		},
	}

	for i, tc := range cases {
		c, err := config.NewRawConfig(tc.Config)
		if err != nil {
			t.Fatalf("err: %s", err)
		}

		err = tc.P.Configure(terraform.NewResourceConfig(c))
		if (err != nil) != tc.Err {
			t.Fatalf("%d: %s", i, err)
		}
	}
}
func TestResourceConfigGet(t *testing.T) {
	cases := []struct {
		Config map[string]interface{}
		Vars   map[string]string
		Key    string
		Value  interface{}
	}{
		{
			Config: nil,
			Key:    "foo",
			Value:  nil,
		},

		{
			Config: map[string]interface{}{
				"foo": "${var.foo}",
			},
			Key:   "foo",
			Value: "${var.foo}",
		},

		{
			Config: map[string]interface{}{
				"foo": "${var.foo}",
			},
			Vars:  map[string]string{"foo": "bar"},
			Key:   "foo",
			Value: "bar",
		},

		{
			Config: map[string]interface{}{
				"foo": []interface{}{1, 2, 5},
			},
			Key:   "foo.0",
			Value: 1,
		},

		{
			Config: map[string]interface{}{
				"foo": []interface{}{1, 2, 5},
			},
			Key:   "foo.5",
			Value: nil,
		},
	}

	for i, tc := range cases {
		var rawC *config.RawConfig
		if tc.Config != nil {
			var err error
			rawC, err = config.NewRawConfig(tc.Config)
			if err != nil {
				t.Fatalf("err: %s", err)
			}
		}

		if tc.Vars != nil {
			vs := make(map[string]ast.Variable)
			for k, v := range tc.Vars {
				vs["var."+k] = ast.Variable{Value: v, Type: ast.TypeString}
			}

			if err := rawC.Interpolate(vs); err != nil {
				t.Fatalf("err: %s", err)
			}
		}

		rc := NewResourceConfig(rawC)
		rc.interpolateForce()

		v, _ := rc.Get(tc.Key)
		if !reflect.DeepEqual(v, tc.Value) {
			t.Fatalf("%d bad: %#v", i, v)
		}
	}
}