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

// loggraphdiff is a tool for interpreting changes to the Terraform graph
// based on the simple graph printing format used in the TF_LOG=trace log
// output from Terraform, which looks like this:
//
//     aws_instance.b (destroy) - *terraform.NodeDestroyResourceInstance
//     aws_instance.b (prepare state) - *terraform.NodeApplyableResource
//       provider.aws - *terraform.NodeApplyableProvider
//     aws_instance.b (prepare state) - *terraform.NodeApplyableResource
//       provider.aws - *terraform.NodeApplyableProvider
//     module.child.aws_instance.a (destroy) - *terraform.NodeDestroyResourceInstance
//       module.child.aws_instance.a (prepare state) - *terraform.NodeApplyableResource
//       module.child.output.a_output - *terraform.NodeApplyableOutput
//       provider.aws - *terraform.NodeApplyableProvider
//     module.child.aws_instance.a (prepare state) - *terraform.NodeApplyableResource
//       provider.aws - *terraform.NodeApplyableProvider
//     module.child.output.a_output - *terraform.NodeApplyableOutput
//       module.child.aws_instance.a (prepare state) - *terraform.NodeApplyableResource
//     provider.aws - *terraform.NodeApplyableProvider
//
// It takes the names of two files containing this style of output and
// produces a single graph description in graphviz format that shows the
// differences between the two graphs: nodes and edges which are only in the
// first graph are shown in red, while those only in the second graph are
// shown in green. This color combination is not useful for those who are
// red/green color blind, so the result can be adjusted by replacing the
// keywords "red" and "green" with a combination that the user is able to
// distinguish.

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"sort"
	"strings"
)

type Graph struct {
	nodes map[string]struct{}
	edges map[[2]string]struct{}
}

func main() {
	if len(os.Args) != 3 {
		log.Fatal("usage: loggraphdiff <old-graph-file> <new-graph-file>")
	}

	old, err := readGraph(os.Args[1])
	if err != nil {
		log.Fatalf("failed to read %s: %s", os.Args[1], err)
	}
	new, err := readGraph(os.Args[2])
	if err != nil {
		log.Fatalf("failed to read %s: %s", os.Args[1], err)
	}

	var nodes []string
	for n := range old.nodes {
		nodes = append(nodes, n)
	}
	for n := range new.nodes {
		if _, exists := old.nodes[n]; !exists {
			nodes = append(nodes, n)
		}
	}
	sort.Strings(nodes)

	var edges [][2]string
	for e := range old.edges {
		edges = append(edges, e)
	}
	for e := range new.edges {
		if _, exists := old.edges[e]; !exists {
			edges = append(edges, e)
		}
	}
	sort.Slice(edges, func(i, j int) bool {
		if edges[i][0] != edges[j][0] {
			return edges[i][0] < edges[j][0]
		}
		return edges[i][1] < edges[j][1]
	})

	fmt.Println("digraph G {")
	fmt.Print("  rankdir = \"BT\";\n\n")
	for _, n := range nodes {
		var attrs string
		_, inOld := old.nodes[n]
		_, inNew := new.nodes[n]
		switch {
		case inOld && inNew:
			// no attrs required
		case inOld:
			attrs = " [color=red]"
		case inNew:
			attrs = " [color=green]"
		}
		fmt.Printf("    %q%s;\n", n, attrs)
	}
	fmt.Println("")
	for _, e := range edges {
		var attrs string
		_, inOld := old.edges[e]
		_, inNew := new.edges[e]
		switch {
		case inOld && inNew:
			// no attrs required
		case inOld:
			attrs = " [color=red]"
		case inNew:
			attrs = " [color=green]"
		}
		fmt.Printf("    %q -> %q%s;\n", e[0], e[1], attrs)
	}
	fmt.Println("}")
}

func readGraph(fn string) (Graph, error) {
	ret := Graph{
		nodes: map[string]struct{}{},
		edges: map[[2]string]struct{}{},
	}
	r, err := os.Open(fn)
	if err != nil {
		return ret, err
	}

	sc := bufio.NewScanner(r)
	var latestNode string
	for sc.Scan() {
		l := sc.Text()
		dash := strings.Index(l, " - ")
		if dash == -1 {
			// invalid line, so we'll ignore it
			continue
		}
		name := l[:dash]
		if strings.HasPrefix(name, "  ") {
			// It's an edge
			name = name[2:]
			edge := [2]string{latestNode, name}
			ret.edges[edge] = struct{}{}
		} else {
			// It's a node
			latestNode = name
			ret.nodes[name] = struct{}{}
		}
	}

	return ret, nil
}
