package pbmsg

// Services returns the unique set of services which were touched in
// the call. Service uniqueness is determined by the checking the
// service's name.
func Services(tx *Transaction) []*Service {
	all := append(callServices(tx.GetRoot()), tx.GetClient())
	deduped := make([]*Service, 0)
	seen := make(map[string]struct{})
	for _, svc := range all {
		if _, ok := seen[svc.GetName()]; !ok {
			seen[svc.GetName()] = struct{}{}
			deduped = append(deduped, svc)
		}
	}
	return deduped
}

func callServices(call *Call) []*Service {
	out := []*Service{call.GetSvc()}
	for _, subcall := range call.GetSubcalls() {
		out = append(out, callServices(subcall)...)
	}
	return out
}

func IsRequestEvent(e *Event) bool {
	switch e.GetKind() {
	case Event_REQUEST_HEAD_PREPARED,
		Event_REQUEST_BODY_SENT,
		Event_REQUEST_HEAD_RECEIVED,
		Event_REQUEST_BODY_RECEIVED:
		return true
	default:
		return false
	}
}

func IsResponseEvent(e *Event) bool {
	switch e.GetKind() {
	case Event_RESPONSE_HEAD_PREPARED,
		Event_RESPONSE_BODY_SENT,
		Event_RESPONSE_HEAD_RECEIVED,
		Event_RESPONSE_BODY_RECEIVED:
		return true
	default:
		return false
	}
}

func IsClientEvent(e *Event) bool {
	switch e.GetKind() {
	case Event_REQUEST_HEAD_PREPARED,
		Event_REQUEST_BODY_SENT,
		Event_RESPONSE_HEAD_RECEIVED,
		Event_RESPONSE_BODY_RECEIVED:
		return true
	default:
		return false
	}
}

func IsServerEvent(e *Event) bool {
	switch e.GetKind() {
	case Event_REQUEST_HEAD_RECEIVED,
		Event_REQUEST_BODY_RECEIVED,
		Event_RESPONSE_HEAD_PREPARED,
		Event_RESPONSE_BODY_SENT:
		return true
	default:
		return false
	}
}
