// Copyright (c) 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
}
