package audit

// FilterByID returns ListAudits with specified ID.
func (la ListAudits) FilterByID(guid string) ListAudits {
	predicate := func(ia ItemAudit) bool {
		return ia.GUID == guid
	}

	return la.FilterFunc(predicate)
}

// FilterByCall returns ListAudits with specified call.
func (la ListAudits) FilterByCall(call string) ListAudits {
	predicate := func(ic ItemAudit) bool {
		return ic.Call == call
	}

	return la.FilterFunc(predicate)
}

// FilterByCorrelationID returns ListAudits with specified correlation id.
func (la ListAudits) FilterByCorrelationID(correlationID string) ListAudits {
	predicate := func(ic ItemAudit) bool {
		return ic.CorrelationID == correlationID
	}

	return la.FilterFunc(predicate)
}

// FilterByRemoteAddr returns ListAudits with specified remote address.
func (la ListAudits) FilterByRemoteAddr(remoteAddr string) ListAudits {
	predicate := func(ic ItemAudit) bool {
		return ic.RemoteAddr == remoteAddr
	}

	return la.FilterFunc(predicate)
}

// FilterByUser returns ListAudits with specified user name.
func (la ListAudits) FilterByUser(user string) ListAudits {
	predicate := func(ic ItemAudit) bool {
		return ic.User == user
	}

	return la.FilterFunc(predicate)
}

// FilterByStatusCode return ListAudits with specified status code.
func (la ListAudits) FilterByStatusCode(statusCode uint64) ListAudits {
	predicate := func(ic ItemAudit) bool {
		return ic.StatusCode == statusCode
	}

	return la.FilterFunc(predicate)

}

// FilterFunc allows filtering ListAudits based on a user-specified predicate.
func (la ListAudits) FilterFunc(predicate func(ItemAudit) bool) ListAudits {
	var result ListAudits

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

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

	return result
}

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

	return la.Data[0]
}
