package pilorama

import "bytes"

// MultiNode represents a group of internal nodes accessible by the same path, but having different id.
type MultiNode []Node

// MultiNodeInfo represents a group of internal nodes accessible by the same path, but having different id.
type MultiNodeInfo struct {
	Children   MultiNode
	Parents    MultiNode
	Timestamps []uint64
	Meta       []KeyValue
}

func (r *MultiNodeInfo) Add(info NodeInfo) bool {
	if !isInternal(info.Meta.Items) || !isInternal(r.Meta) ||
		!bytes.Equal(r.Meta[0].Value, info.Meta.Items[0].Value) {
		return false
	}

	r.Children = append(r.Children, info.ID)
	r.Parents = append(r.Parents, info.ParentID)
	r.Timestamps = append(r.Timestamps, info.Meta.Time)
	return true
}

func (n NodeInfo) ToMultiNode() MultiNodeInfo {
	return MultiNodeInfo{
		Children:   MultiNode{n.ID},
		Parents:    MultiNode{n.ParentID},
		Timestamps: []uint64{n.Meta.Time},
		Meta:       n.Meta.Items,
	}
}

func isInternal(m []KeyValue) bool {
	return len(m) == 1 && m[0].Key == AttributeFilename
}

func mergeNodeInfos(ns []NodeInfo) []MultiNodeInfo {
	var r []MultiNodeInfo
	for _, info := range ns {
		if len(r) == 0 || !r[len(r)-1].Add(info) {
			r = append(r, info.ToMultiNode())
		}
	}
	return r
}