package node

// FilterByID returns ListNodes with specified ID.
func (ln ListNodes) FilterByID(id uint64) ListNodes {
	predicate := func(in ItemNode) bool {
		return in.ID == id
	}

	return ln.FilterFunc(predicate)
}

// FilterByName returns ListNodes with specified Name.
func (ln ListNodes) FilterByName(name string) ListNodes {
	predicate := func(in ItemNode) bool {
		return in.Name == name
	}

	return ln.FilterFunc(predicate)
}

// FilterByVersion return ListNodes with specified version.
func (ln ListNodes) FilterByVersion(version string) ListNodes {
	predicate := func(in ItemNode) bool {
		return in.Version == version
	}

	return ln.FilterFunc(predicate)
}

// FilterByRelease returns ListNodes with specified Release.
func (ln ListNodes) FilterByRelease(release string) ListNodes {
	predicate := func(in ItemNode) bool {
		return in.Release == release
	}

	return ln.FilterFunc(predicate)
}

// FilterBySepID returns ListNodes with specified Sep ID.
func (ln ListNodes) FilterBySepID(sepId uint64) ListNodes {
	predicate := func(in ItemNode) bool {
		for _, s := range in.Seps {
			if s == sepId {
				return true
			}
		}
		return false
	}

	return ln.FilterFunc(predicate)
}

// FilterByRole returns ListNodes with specified Role.
func (ln ListNodes) FilterByRole(role string) ListNodes {
	predicate := func(in ItemNode) bool {
		for _, r := range in.Roles {
			if r == role {
				return true
			}
		}
		return false
	}

	return ln.FilterFunc(predicate)
}

// FilterByStatus return ListNodes with specified status.
func (ln ListNodes) FilterByStatus(status string) ListNodes {
	predicate := func(in ItemNode) bool {
		return in.Status == status
	}

	return ln.FilterFunc(predicate)
}

// FilterFunc allows filtering ListNodes based on a user-specified predicate.
func (ln ListNodes) FilterFunc(predicate func(ItemNode) bool) ListNodes {
	var result ListNodes

	for _, item := range ln.Data {
		if predicate(item) {
			result.Data = append(result.Data, item)
		}
	}

	result.EntryCount = uint64(len(result.Data))

	return result
}

// FindOne returns first found ItemNode.
// If none was found, returns an empty struct.
func (ln ListNodes) FindOne() ItemNode {
	if len(ln.Data) == 0 {
		return ItemNode{}
	}

	return ln.Data[0]
}
