FactoryResult.java

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

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

import javax.lang.model.type.TypeMirror;
import java.util.Set;

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

public record FactoryResult<T extends Converter>(
        StoreID id,
        SourceDV source,
        Msg.Messages messages,
        @Nullable T converter,
        Converter.@Nullable Placeholder placeholder,
        Set<StoreID> dependent) {

    public static <T extends Converter> FactoryResult<T> of(StoreID id, T converter) {
        return new FactoryResult<>(id, converter.source(), Msg.empty(), converter, null, Set.of());
    }

    public static <T extends Converter> FactoryResult<T> of(StoreID id, Converter.Placeholder placeholder) {
        return new FactoryResult<>(id, placeholder.source(), Msg.empty(), null, placeholder, Set.of());
    }

    public static <T extends Converter> FactoryResult<T> of(StoreID id, SourceDV source, Msg.Messages messages) {
        return of(id, source, messages, Set.of());
    }

    public static <T extends Converter> FactoryResult<T> of(StoreID id, SourceDV source, Msg.Messages messages, Set<StoreID> dependent) {
        if (!messages.hasMessages()) {
            throw new IllegalArgumentException();
        }
        return new FactoryResult<>(id, source, messages, null, null, dependent);
    }

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

    public FactoryResult<T> newWithMessages(Msg.Messages messages) {
        return this.newWithMessages(messages, Set.of());
    }

    public FactoryResult<T> newWithMessages(Msg.Messages messages, Set<StoreID> dependent) {
        if (!messages.hasMessages()) {
            throw new IllegalArgumentException();
        }
        return new FactoryResult<>(this.id, this.source, messages, null, null, dependent);
    }

    public TypeMirror type() {
        if (this.converter != null) {
            return this.converter.type();
        } else if (this.placeholder != null) {
            return this.placeholder.type();
        }
        throw new IllegalStateException(this.toString());
    }

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

    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 hasPlaceholder() {
        return this.placeholder != null;
    }

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

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

    @Override
    public String toString() {
        return "{id=" + id
                + ", source=" + source //
                + (messages.hasMessages() ? ", messages=" + messages : "") //
                + (converter != null ? ", converter=" + converter : "") //
                + (placeholder != null ? ", placeholder=" + placeholder : "") //
                + (!dependent.isEmpty() ? ", dependent=" + dependent : "") //
                + '}';
    }
}