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

package statefile

import (
	"sort"
	"strings"
	"testing"

	"github.com/hashicorp/terraform/internal/tfdiags"
	"github.com/zclconf/go-cty/cty"
)

// This test verifies that modules are sorted before resources:
// https://github.com/hashicorp/terraform/issues/21552
func TestVersion4_sort(t *testing.T) {
	resources := sortResourcesV4{
		{
			Module: "module.child",
			Type:   "test_instance",
			Name:   "foo",
		},
		{
			Type: "test_instance",
			Name: "foo",
		},
		{
			Module: "module.kinder",
			Type:   "test_instance",
			Name:   "foo",
		},
		{
			Module: "module.child.grandchild",
			Type:   "test_instance",
			Name:   "foo",
		},
	}
	sort.Stable(resources)

	moduleOrder := []string{"", "module.child", "module.child.grandchild", "module.kinder"}

	for i, resource := range resources {
		if resource.Module != moduleOrder[i] {
			t.Errorf("wrong sort order: expected %q, got %q\n", moduleOrder[i], resource.Module)
		}
	}
}

func TestVersion4_unmarshalPaths(t *testing.T) {
	testCases := map[string]struct {
		json  string
		paths []cty.Path
		diags []string
	}{
		"no paths": {
			json:  `[]`,
			paths: []cty.Path{},
		},
		"attribute path": {
			json: `[
  [
    {
      "type": "get_attr",
	  "value": "password"
    }
  ]
]`,
			paths: []cty.Path{cty.GetAttrPath("password")},
		},
		"attribute and string index": {
			json: `[
  [
    {
      "type": "get_attr",
	  "value": "triggers"
    },
    {
      "type": "index",
      "value": {
        "value": "secret",
		"type": "string"
      }
    }
  ]
]`,
			paths: []cty.Path{cty.GetAttrPath("triggers").IndexString("secret")},
		},
		"attribute, number index, attribute": {
			json: `[
  [
    {
      "type": "get_attr",
	  "value": "identities"
    },
    {
      "type": "index",
      "value": {
        "value": 2,
		"type": "number"
      }
    },
    {
      "type": "get_attr",
      "value": "private_key"
    }
  ]
]`,
			paths: []cty.Path{cty.GetAttrPath("identities").IndexInt(2).GetAttr("private_key")},
		},
		"multiple paths": {
			json: `[
  [
    {
      "type": "get_attr",
	  "value": "alpha"
    }
  ],
  [
    {
      "type": "get_attr",
	  "value": "beta"
    }
  ],
  [
    {
      "type": "get_attr",
	  "value": "gamma"
    }
  ]
]`,
			paths: []cty.Path{cty.GetAttrPath("alpha"), cty.GetAttrPath("beta"), cty.GetAttrPath("gamma")},
		},
		"errors": {
			json: `[
  [
    {
      "type": "get_attr",
	  "value": 5
    }
  ],
  [
    {
      "type": "index",
	  "value": "test"
    }
  ],
  [
    {
      "type": "invalid_type",
	  "value": ["this is invalid too"]
    }
  ]
]`,
			paths: []cty.Path{},
			diags: []string{
				"Failed to unmarshal get attr step name",
				"Failed to unmarshal index step key",
				"Unsupported path step",
			},
		},
		"one invalid path, others valid": {
			json: `[
  [
    {
      "type": "get_attr",
	  "value": "alpha"
    }
  ],
  [
    {
      "type": "invalid_type",
	  "value": ["this is invalid too"]
    }
  ],
  [
    {
      "type": "get_attr",
	  "value": "gamma"
    }
  ]
]`,
			paths: []cty.Path{cty.GetAttrPath("alpha"), cty.GetAttrPath("gamma")},
			diags: []string{"Unsupported path step"},
		},
		"invalid structure": {
			json:  `{}`,
			paths: []cty.Path{},
			diags: []string{"Error unmarshaling path steps"},
		},
	}

	for name, tc := range testCases {
		t.Run(name, func(t *testing.T) {
			paths, diags := unmarshalPaths([]byte(tc.json))

			if len(tc.diags) == 0 {
				if len(diags) != 0 {
					t.Errorf("expected no diags, got: %#v", diags)
				}
			} else {
				if got, want := len(diags), len(tc.diags); got != want {
					t.Fatalf("got %d diags, want %d\n%s", got, want, diags.Err())
				}
				for i := range tc.diags {
					got := tfdiags.Diagnostics{diags[i]}.Err().Error()
					if !strings.Contains(got, tc.diags[i]) {
						t.Errorf("expected diag %d to contain %q, but was:\n%s", i, tc.diags[i], got)
					}
				}
			}

			if len(paths) != len(tc.paths) {
				t.Fatalf("got %d paths, want %d", len(paths), len(tc.paths))
			}
			for i, path := range paths {
				if !path.Equals(tc.paths[i]) {
					t.Errorf("wrong paths\n got: %#v\nwant: %#v", path, tc.paths[i])
				}
			}
		})
	}
}

func TestVersion4_marshalPaths(t *testing.T) {
	testCases := map[string]struct {
		paths []cty.Path
		json  string
	}{
		"no paths": {
			paths: []cty.Path{},
			json:  `[]`,
		},
		"attribute path": {
			paths: []cty.Path{cty.GetAttrPath("password")},
			json:  `[[{"type":"get_attr","value":"password"}]]`,
		},
		"attribute, number index, attribute": {
			paths: []cty.Path{cty.GetAttrPath("identities").IndexInt(2).GetAttr("private_key")},
			json:  `[[{"type":"get_attr","value":"identities"},{"type":"index","value":{"value":2,"type":"number"}},{"type":"get_attr","value":"private_key"}]]`,
		},
		"multiple paths": {
			paths: []cty.Path{cty.GetAttrPath("a"), cty.GetAttrPath("b"), cty.GetAttrPath("c")},
			json:  `[[{"type":"get_attr","value":"a"}],[{"type":"get_attr","value":"b"}],[{"type":"get_attr","value":"c"}]]`,
		},
	}

	for name, tc := range testCases {
		t.Run(name, func(t *testing.T) {
			json, diags := marshalPaths(tc.paths)

			if len(diags) != 0 {
				t.Fatalf("expected no diags, got: %#v", diags)
			}

			if got, want := string(json), tc.json; got != want {
				t.Fatalf("wrong JSON output\n got: %s\nwant: %s\n", got, want)
			}
		})
	}
}
