package callgraph

import (
	"fmt"
	"sort"
	"strings"
)

func signature(n Node) string {
	from := trimRepo(n.Label(Client))
	to := trimRepo(n.Label(Server))

	if name := n.Label(RPCName); name != UnknownRPC {
		to = to + ":" + name
	}

	deps := fmt.Sprintf(" [%s]", strings.Join(AllDependencies(n), ", "))
	sig := fmt.Sprintf("%s->%s%s", from, to, deps)
	return sig
}

// Dependencies returns a sorted slice of the servers that this node
// immediately depended upon in the call graph.
func Dependencies(n Node) []string {
	servers := make([]string, 0)
	set := make(map[string]struct{})
	var server string
	for _, child := range n.Children() {
		server = child.Label(Server)
		if _, ok := set[server]; !ok {
			servers = append(servers, server)
			set[server] = struct{}{}
		}
	}
	sort.Strings(servers)
	return servers
}

// AllDependencies returns a sorted slice of all servers touched in
// the subtree below this node.
func AllDependencies(n Node) []string {
	servers := Dependencies(n)
	for _, child := range n.Children() {
		servers = append(servers, Dependencies(child)...)
	}

	deduped := make([]string, 0)
	set := make(map[string]struct{})
	for _, dep := range servers {
		if _, ok := set[dep]; !ok {
			deduped = append(deduped, dep)
			set[dep] = struct{}{}
		}
	}
	sort.Strings(deduped)
	return deduped
}
