package tx

import (
	"math/rand"

	"code.justin.tv/release/trace/analysis/callgraph"
)

const NumExamples = 5

// SignatureSet is a TransactionSet which provides information on a
// collection of transactions with a common signature.
type SignatureSet struct {
	InMemoryTransactionSet

	Signature string
	Examples  []*Transaction
}

func NewSignatureSet(sig string, txs TransactionSet) *SignatureSet {
	ts := NewInMemoryTransactionSet().(*InMemoryTransactionSet)
	ss := &SignatureSet{
		*ts,
		sig,
		make([]*Transaction, 0, NumExamples),
	}
	var p float64
	for i, tx := range txs.All() {
		ss.Add(tx)
		// As we stream the transactions in, pluck out examples with a
		// streaming random sample.
		if i < NumExamples {
			ss.Examples = append(ss.Examples, tx)
		} else {
			p = float64(NumExamples) / float64(i+1)
			if rand.Float64() < p {
				idx := rand.Intn(NumExamples)
				ss.Examples[idx] = tx
			}
		}
	}
	return ss
}

// Returns the RPCName of the root call for all transactions with this
// signature.
func (ss *SignatureSet) RootRPC() string {
	return ss.Examples[0].Root.Label(callgraph.RPCName)
}

// Returns the list of immediate dependencies for the root span of a
// transaction which matches this signature.
func (ss *SignatureSet) Dependencies() []string {
	return callgraph.Dependencies(ss.Examples[0].Root)
}

// Returns the list of immediate dependencies for the root span of a
// transaction which matches this signature.
func (ss *SignatureSet) AllDependencies() []string {
	return callgraph.AllDependencies(ss.Examples[0].Root)
}
