package message

import "strings"

func normalizeMessageSearchCursor(cursor MessageSearchCursor) (MessageSearchCursor, error) {
	cursor.ScopeID = strings.TrimSpace(cursor.ScopeID)
	cursor.MessageID = strings.TrimSpace(cursor.MessageID)
	if cursor.Rank < 0 || cursor.GlobalSeq < 0 || cursor.Seq < 0 {
		return MessageSearchCursor{}, badRequest("invalid search cursor")
	}
	return cursor, nil
}

func normalizeCompleteMessageSearchCursor(cursor MessageSearchCursor, scopeID string) (MessageSearchCursor, error) {
	cursor, err := normalizeMessageSearchCursor(cursor)
	if err != nil {
		return MessageSearchCursor{}, err
	}
	if cursor.IsZero() {
		return MessageSearchCursor{}, nil
	}

	scopeID = strings.TrimSpace(scopeID)
	if scopeID != "" {
		if cursor.ScopeID != "" && cursor.ScopeID != scopeID {
			return MessageSearchCursor{}, badRequest("invalid search cursor")
		}
		if cursor.Seq <= 0 || cursor.MessageID == "" {
			return MessageSearchCursor{}, badRequest("invalid search cursor")
		}
		cursor.GlobalSeq = 0
		cursor.ScopeID = scopeID
		return cursor, nil
	}

	if cursor.GlobalSeq <= 0 || cursor.ScopeID == "" || cursor.Seq <= 0 || cursor.MessageID == "" {
		return MessageSearchCursor{}, badRequest("invalid search cursor")
	}
	return cursor, nil
}

func normalizeScopeAPISearchCursor(request ScopeAPISearchRequest, scopeID string) (MessageSearchCursor, error) {
	cursor, err := normalizeMessageSearchCursor(request.BeforeCursor)
	if err != nil {
		return MessageSearchCursor{}, invalidArgument("invalid search cursor")
	}
	if !cursor.IsZero() {
		cursor, err = normalizeCompleteMessageSearchCursor(cursor, scopeID)
		if err != nil {
			return MessageSearchCursor{}, invalidArgument("invalid search cursor")
		}
		return cursor, nil
	}
	if request.BeforeSeq < 0 {
		return MessageSearchCursor{}, invalidArgument("invalid search cursor")
	}
	if request.BeforeSeq == 0 {
		return MessageSearchCursor{}, nil
	}
	if strings.TrimSpace(scopeID) != "" {
		return MessageSearchCursor{Seq: request.BeforeSeq}, nil
	}
	return MessageSearchCursor{GlobalSeq: request.BeforeSeq}, nil
}

func searchCandidateCursor(message ScopeMessageRecord, scopeID string, searchRank int) MessageSearchCursor {
	scopeID = strings.TrimSpace(scopeID)
	if scopeID != "" {
		return MessageSearchCursor{
			Rank:      searchRank,
			ScopeID:   scopeID,
			Seq:       message.Seq,
			MessageID: strings.TrimSpace(message.ID),
		}
	}
	return MessageSearchCursor{
		Rank:      searchRank,
		GlobalSeq: message.WorkspaceGlobalSeq,
		ScopeID:   strings.TrimSpace(message.ScopeID),
		Seq:       message.Seq,
		MessageID: strings.TrimSpace(message.ID),
	}
}
