package {{ package_name }}.internal;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;

public abstract class AbstractDelegate<T> {
    private final RpcCaller client;
    private final String modelName;

    protected AbstractDelegate(RpcCaller client, String modelName) {
        this.client = client;
        this.modelName = modelName;
    }

    protected final JsonNode rpc(String method, ObjectNode params) {
        return this.client.rpc(method, params);
    }

    protected final Stream<JsonNode> streamRpc(String method, ObjectNode params) {
        return this.client.streamRpc(method, params);
    }

    protected final <R> CompletableFuture<R> async(Supplier<R> supplier) {
        return CompletableFuture.supplyAsync(supplier, this.client.executor());
    }

    protected final <R> List<R> rows(JsonNode result, Function<JsonNode, R> mapper) {
        return JsonSupport.dataList(result, mapper);
    }

    protected final ArrayNode createDataArray(List<? extends WireSerializable> items) {
        ArrayNode array = JsonSupport.array();
        for (WireSerializable item : items) {
            array.add(item.toJsonNode());
        }
        return array;
    }

    protected final <R> Stream<R> rows(Stream<JsonNode> results, Function<JsonNode, R> mapper) {
        return results.flatMap(result -> JsonSupport.dataList(result, mapper).stream());
    }
}
