package callgraph

import (
	"encoding/json"

	"code.justin.tv/release/trace/pbmsg"
)

// Node represents an element of an analyzable tree.
type Node interface {
	// Children returns the nodes which are descendants in the tree
	Children() []Node
	// Label returns a single string value to describe the node along
	// some dimension
	Label(StringDimension) string
	// IntValue returns a single integer value to describe the node
	// along a dimension
	IntValue(Int64Dimension) int64
}

// CallNode represents an element of an analyzable call tree
type CallNode interface {
	Node
	json.Marshaler
	// Add adds data from an event to the call tree
	Add(*pbmsg.Event)
}

// Labels returns the value of node.Label(dim) for every node in the
// tree starting with the given root node.
func Labels(root Node, dim StringDimension) []string {
	out := []string{root.Label(dim)}
	for _, child := range root.Children() {
		out = append(out, Labels(child, dim)...)
	}
	return out
}

// IntValues returns the value of node.IntValue(dim) for every node in the
// tree starting with the given root node.
func IntValues(root Node, dim Int64Dimension) []int64 {
	out := []int64{root.IntValue(dim)}
	for _, child := range root.Children() {
		out = append(out, IntValues(child, dim)...)
	}
	return out
}
