SearchResult.java

/*
 * SPDX-FileCopyrightText: 2025 kaumei.io
 * SPDX-License-Identifier: Apache-2.0
 */
package io.kaumei.jdbc.anno.store;

import io.kaumei.jdbc.anno.msg.JdbcMsg;
import io.kaumei.jdbc.anno.msg.Msg;
import org.jspecify.annotations.Nullable;

import java.util.List;

import static io.kaumei.jdbc.anno.utils.AnnoUtils.requireState;

public class SearchResult<T extends Converter> {

    public static <T extends Converter> SearchResult<T> cycle(StoreID storeId, List<StoreID> cycle) {
        return new SearchResult<>(storeId, SearchState.DYNAMIC_CYCLE, JdbcMsg.cycle(cycle), null, null, null);
    }

    public static <T extends Converter> SearchResult<T> notFound(StoreID storeId) {
        return new SearchResult<>(storeId, SearchState.NOT_FOUND, JdbcMsg.NOT_FOUND, null, null, null);
    }

    public static <T extends Converter> SearchResult<T> valid(StoreID storeId, SearchState state, Store<T> store, @Nullable T converter, Converter.@Nullable Placeholder placeholder) {
        if ((converter == null && placeholder == null) || (converter != null && placeholder != null)) { // sanity-check
            throw new IllegalArgumentException("converter=" + converter + ", placeholder=" + placeholder); // sanity-check
        }
        return new SearchResult<>(storeId, state, Msg.empty(), store, converter, placeholder);
    }

    public static <T extends Converter> SearchResult<T> invalid(StoreID storeId, SearchState state, Store<T> store, Msg.Messages messages) {
        if (!messages.hasMessages()) { // sanity-check
            throw new IllegalArgumentException("Messages must not be empty"); // sanity-check
        }
        return new SearchResult<>(storeId, state, messages, store, null, null);
    }

    // ------------------------------------------------------------------------

    private final StoreID storeId;
    private final SearchState state;
    private final Msg.Messages messages;
    private final @Nullable Store<T> store;
    private final @Nullable T converter;
    private final Converter.@Nullable Placeholder placeholder;

    SearchResult(StoreID storeId, SearchState state, Msg.Messages messages,
                 @Nullable Store<T> store,
                 @Nullable T converter, Converter.@Nullable Placeholder placeholder) {
        this.storeId = storeId;
        this.state = state;
        this.messages = messages;
        this.converter = converter;
        this.store = store;
        this.placeholder = placeholder;
    }

    public StoreID storeId() {
        return this.storeId;
    }

    public SearchState state() {
        return this.state;
    }

    // ------------------------------------------------------------------------

    public boolean hasMessages() {
        return this.messages.hasMessages();
    }

    public Msg.Messages messages() {
        return this.messages;
    }

    // ------------------------------------------------------------------------

    public boolean hasConverter() {
        return this.converter != null;
    }

    public T converter() {
        return requireState(this.converter, this::toString);
    }

    // ------------------------------------------------------------------------

    public boolean hasStore() {
        return this.store != null;
    }

    public Store<T> store() {
        return requireState(this.store, this::toString);
    }

    // ------------------------------------------------------------------------

    public boolean hasPlaceholder() {
        return this.placeholder != null;
    }

    public Converter.Placeholder placeholder() {
        return requireState(this.placeholder, this::toString);
    }

    // ------------------------------------------------------------------------

    @Override
    public String toString() {
        return "{storeId=" + storeId + ", state=" + state
                + (messages.hasMessages() ? ", messages=" + messages : "") //
                + (converter != null ? ", converter=" + converter : "") //
                + (store != null ? ", store=" + store : "") //
                + (placeholder != null ? ", placeholder=" + placeholder : "") //
                + '}';
    }

}