package ru.dragonestia.kubik.client;

import com.google.gson.Gson;
import lombok.Getter;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import ru.dragonestia.kubik.client.proxy.ProxyControl;
import ru.dragonestia.kubik.client.proxy.ProxyServerRegistry;
import ru.dragonestia.kubik.client.server.ServerControl;
import ru.dragonestia.kubik.dto.ServerData;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

public class Kubik {

    private final static Gson gson = new Gson();

    @Getter private final String httpUrl;
    @Getter private final String wsUrl;
    @Getter private final KubikConfig config;
    @Getter private final OkHttpClient okHttpClient;
    private final ScheduledExecutorService executor;

    public Kubik(String httpUrl, String wsUrl) {
        this(httpUrl, wsUrl, KubikConfig.builder().build());
    }

    public Kubik(String httpUrl, String wsUrl, KubikConfig config) {
        this.httpUrl = httpUrl;
        this.wsUrl = wsUrl;
        this.config = config;
        this.executor = Executors.newScheduledThreadPool(config.getThreadPoolSize());
        this.okHttpClient = new OkHttpClient.Builder().build();
    }

    public ServerControl initServer(String groupId, int port) {
        return new ServerControl(this, executor, groupId, port);
    }

    public ProxyControl initProxy(ProxyServerRegistry registry) {
        return new ProxyControl(this, executor, registry);
    }

    public String pickServer(String groupId) {
        var request = new Request.Builder()
                .url(HttpUrl.get(getHttpUrl() + "/api/v1/server").newBuilder()
                        .addQueryParameter("groupId", groupId)
                        .build())
                .get()
                .build();

        try (var response = getOkHttpClient().newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new RuntimeException("Taken bad response: %s, %s".formatted(response.code(), response.message()));
            }
            var data = gson.fromJson(response.body().string(), ServerData.class);
            return data.id();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    static void main() throws InterruptedException {
        var kubik = new Kubik("http://localhost:8080", "ws://localhost:8080");
        var serverControl = kubik.initServer("TestServer", 19136);
        var proxyControl = kubik.initProxy(new ProxyServerRegistry() {

            @Override
            public void register(String id, String address, int port) {
                System.out.println("Registering " + id + " to " + address + ":" + port);
            }

            @Override
            public void unregister(String id) {
                System.out.println("Unregistering " + id);
            }
        });
    }
}
