package tx

import "sort"

type SortOrder int

const (
	Unsorted SortOrder = iota
	ByTime
	ByDepth
	BySize
)

// Sort re-sorts the given transactions by the given ordering. It
// creates a new slice, copying the entire input slice in the process.
func Sort(order SortOrder, txs []*Transaction) []*Transaction {
	newTxs := make([]*Transaction, len(txs))
	copy(newTxs, txs)

	data := txsWithInt64{
		vals: newTxs,
		keys: make([]int64, len(newTxs)),
	}
	switch order {
	case ByTime:
		for i, tx := range data.vals {
			data.keys[i] = int64(tx.RootDuration())
		}
	case ByDepth:
		for i, tx := range data.vals {
			data.keys[i] = int64(tx.Depth())
		}
	case BySize:
		for i, tx := range data.vals {
			data.keys[i] = int64(tx.Size())
		}
	}
	sort.Sort(data)

	return newTxs
}

type txsWithInt64 struct {
	vals []*Transaction
	keys []int64
}

func (t txsWithInt64) Len() int           { return len(t.vals) }
func (t txsWithInt64) Less(i, j int) bool { return t.keys[i] < t.keys[j] }
func (t txsWithInt64) Swap(i, j int) {
	t.vals[i], t.vals[j] = t.vals[j], t.vals[i]
	t.keys[i], t.keys[j] = t.keys[j], t.keys[i]
}
