package terraform

import (
	"strings"
	"testing"

	"github.com/hashicorp/terraform/internal/dag"
)

func TestGraphDot(t *testing.T) {
	cases := []struct {
		Name   string
		Graph  testGraphFunc
		Opts   dag.DotOpts
		Expect string
		Error  string
	}{
		{
			Name:  "empty",
			Graph: func() *Graph { return &Graph{} },
			Expect: `
digraph {
	compound = "true"
	newrank = "true"
	subgraph "root" {
	}
}`,
		},
		{
			Name: "three-level",
			Graph: func() *Graph {
				var g Graph
				root := &testDrawableOrigin{"root"}
				g.Add(root)

				levelOne := []interface{}{"foo", "bar"}
				for i, s := range levelOne {
					levelOne[i] = &testDrawable{
						VertexName: s.(string),
					}
					v := levelOne[i]

					g.Add(v)
					g.Connect(dag.BasicEdge(v, root))
				}

				levelTwo := []string{"baz", "qux"}
				for i, s := range levelTwo {
					v := &testDrawable{
						VertexName: s,
					}

					g.Add(v)
					g.Connect(dag.BasicEdge(v, levelOne[i]))
				}

				return &g
			},
			Expect: `
digraph {
	compound = "true"
	newrank = "true"
	subgraph "root" {
		"[root] bar"
		"[root] baz"
		"[root] foo"
		"[root] qux"
		"[root] root"
		"[root] bar" -> "[root] root"
		"[root] baz" -> "[root] foo"
		"[root] foo" -> "[root] root"
		"[root] qux" -> "[root] bar"
	}
}
			`,
		},

		{
			Name: "cycle",
			Opts: dag.DotOpts{
				DrawCycles: true,
			},
			Graph: func() *Graph {
				var g Graph
				root := &testDrawableOrigin{"root"}
				g.Add(root)

				vA := g.Add(&testDrawable{
					VertexName: "A",
				})

				vB := g.Add(&testDrawable{
					VertexName: "B",
				})

				vC := g.Add(&testDrawable{
					VertexName: "C",
				})

				g.Connect(dag.BasicEdge(vA, root))
				g.Connect(dag.BasicEdge(vA, vC))
				g.Connect(dag.BasicEdge(vB, vA))
				g.Connect(dag.BasicEdge(vC, vB))

				return &g
			},
			Expect: `
digraph {
	compound = "true"
	newrank = "true"
	subgraph "root" {
		"[root] A"
		"[root] B"
		"[root] C"
		"[root] root"
		"[root] A" -> "[root] B" [color = "red", penwidth = "2.0"]
		"[root] A" -> "[root] C"
		"[root] A" -> "[root] root"
		"[root] B" -> "[root] A"
		"[root] B" -> "[root] C" [color = "red", penwidth = "2.0"]
		"[root] C" -> "[root] A" [color = "red", penwidth = "2.0"]
		"[root] C" -> "[root] B"
	}
}
					`,
		},

		{
			Name: "subgraphs, no depth restriction",
			Opts: dag.DotOpts{
				MaxDepth: -1,
			},
			Graph: func() *Graph {
				var g Graph
				root := &testDrawableOrigin{"root"}
				g.Add(root)

				var sub Graph
				vSubRoot := sub.Add(&testDrawableOrigin{"sub_root"})

				var subsub Graph
				subsub.Add(&testDrawableOrigin{"subsub_root"})
				vSubV := sub.Add(&testDrawableSubgraph{
					VertexName:   "subsub",
					SubgraphMock: &subsub,
				})

				vSub := g.Add(&testDrawableSubgraph{
					VertexName:   "sub",
					SubgraphMock: &sub,
				})

				g.Connect(dag.BasicEdge(vSub, root))
				sub.Connect(dag.BasicEdge(vSubV, vSubRoot))

				return &g
			},
			Expect: `
digraph {
	compound = "true"
	newrank = "true"
	subgraph "root" {
		"[root] root"
		"[root] sub"
		"[root] sub" -> "[root] root"
	}
	subgraph "cluster_sub" {
		label = "sub"
		"[sub] sub_root"
		"[sub] subsub"
		"[sub] subsub" -> "[sub] sub_root"
	}
	subgraph "cluster_subsub" {
		label = "subsub"
		"[subsub] subsub_root"
	}
}
						`,
		},

		{
			Name: "subgraphs, with depth restriction",
			Opts: dag.DotOpts{
				MaxDepth: 1,
			},
			Graph: func() *Graph {
				var g Graph
				root := &testDrawableOrigin{"root"}
				g.Add(root)

				var sub Graph
				rootSub := sub.Add(&testDrawableOrigin{"sub_root"})

				var subsub Graph
				subsub.Add(&testDrawableOrigin{"subsub_root"})

				subV := sub.Add(&testDrawableSubgraph{
					VertexName:   "subsub",
					SubgraphMock: &subsub,
				})
				vSub := g.Add(&testDrawableSubgraph{
					VertexName:   "sub",
					SubgraphMock: &sub,
				})

				g.Connect(dag.BasicEdge(vSub, root))
				sub.Connect(dag.BasicEdge(subV, rootSub))
				return &g
			},
			Expect: `
digraph {
	compound = "true"
	newrank = "true"
	subgraph "root" {
		"[root] root"
		"[root] sub"
		"[root] sub" -> "[root] root"
	}
	subgraph "cluster_sub" {
		label = "sub"
		"[sub] sub_root"
		"[sub] subsub"
		"[sub] subsub" -> "[sub] sub_root"
	}
}
						`,
		},
	}

	for _, tc := range cases {
		tn := tc.Name
		t.Run(tn, func(t *testing.T) {
			g := tc.Graph()
			var err error
			//actual, err := GraphDot(g, &tc.Opts)
			actual := string(g.Dot(&tc.Opts))

			if err == nil && tc.Error != "" {
				t.Fatalf("%s: expected err: %s, got none", tn, tc.Error)
			}
			if err != nil && tc.Error == "" {
				t.Fatalf("%s: unexpected err: %s", tn, err)
			}
			if err != nil && tc.Error != "" {
				if !strings.Contains(err.Error(), tc.Error) {
					t.Fatalf("%s: expected err: %s\nto contain: %s", tn, err, tc.Error)
				}
				return
			}

			expected := strings.TrimSpace(tc.Expect) + "\n"
			if actual != expected {
				t.Fatalf("%s:\n\nexpected:\n%s\n\ngot:\n%s", tn, expected, actual)
			}
		})
	}
}

type testGraphFunc func() *Graph

type testDrawable struct {
	VertexName      string
	DependentOnMock []string
}

func (node *testDrawable) Name() string {
	return node.VertexName
}
func (node *testDrawable) DotNode(n string, opts *dag.DotOpts) *dag.DotNode {
	return &dag.DotNode{Name: n, Attrs: map[string]string{}}
}
func (node *testDrawable) DependableName() []string {
	return []string{node.VertexName}
}
func (node *testDrawable) DependentOn() []string {
	return node.DependentOnMock
}

type testDrawableOrigin struct {
	VertexName string
}

func (node *testDrawableOrigin) Name() string {
	return node.VertexName
}
func (node *testDrawableOrigin) DotNode(n string, opts *dag.DotOpts) *dag.DotNode {
	return &dag.DotNode{Name: n, Attrs: map[string]string{}}
}
func (node *testDrawableOrigin) DotOrigin() bool {
	return true
}
func (node *testDrawableOrigin) DependableName() []string {
	return []string{node.VertexName}
}

type testDrawableSubgraph struct {
	VertexName      string
	SubgraphMock    *Graph
	DependentOnMock []string
}

func (node *testDrawableSubgraph) Name() string {
	return node.VertexName
}
func (node *testDrawableSubgraph) Subgraph() dag.Grapher {
	return node.SubgraphMock
}
func (node *testDrawableSubgraph) DotNode(n string, opts *dag.DotOpts) *dag.DotNode {
	return &dag.DotNode{Name: n, Attrs: map[string]string{}}
}
func (node *testDrawableSubgraph) DependentOn() []string {
	return node.DependentOnMock
}
