package zenith.zov.base.cloud;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.charset.StandardCharsets;
import java.time.Duration;

public class CloudConfigService {
    private final HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5L)).build();
    private final String baseUrl;

    public CloudConfigService(String baseUrl) {
        this.baseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
    }

    public String uploadConfig(String encryptedBase64Content) throws IOException, InterruptedException {
        String body = "{\"data\":\"" + escapeJson(encryptedBase64Content) + "\"}";
        HttpRequest req = HttpRequest.newBuilder()
            .uri(URI.create(this.baseUrl + "/configs"))
            .timeout(Duration.ofSeconds(10L))
            .header("Content-Type", "application/json")
            .POST(BodyPublishers.ofString(body, StandardCharsets.UTF_8))
            .build();
        HttpResponse<String> resp = this.client.send(req, BodyHandlers.ofString(StandardCharsets.UTF_8));
        if (resp.statusCode() / 100 != 2) {
            throw new IOException("Upload failed: HTTP " + resp.statusCode());
        } else {
            String json = resp.body();
            String id = extractJsonField(json, "id");
            if (id != null && !id.isBlank()) {
                return id;
            } else {
                throw new IOException("Malformed response from server");
            }
        }
    }

    public String downloadConfig(String id) throws IOException, InterruptedException {
        HttpRequest req = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + "/configs/" + id)).timeout(Duration.ofSeconds(10L)).GET().build();
        HttpResponse<String> resp = this.client.send(req, BodyHandlers.ofString(StandardCharsets.UTF_8));
        if (resp.statusCode() == 404) {
            throw new IOException("Config not found");
        } else if (resp.statusCode() / 100 != 2) {
            throw new IOException("Download failed: HTTP " + resp.statusCode());
        } else {
            String json = resp.body();
            String data = extractJsonField(json, "data");
            if (data == null) {
                throw new IOException("Malformed response from server");
            } else {
                return data;
            }
        }
    }

    private static String escapeJson(String s) {
        return s.replace("\\", "\\\\").replace("\"", "\\\"");
    }

    private static String extractJsonField(String json, String field) {
        String key = "\"" + field + "\"";
        int i = json.indexOf(key);
        if (i < 0) {
            return null;
        } else {
            int colon = json.indexOf(58, i + key.length());
            if (colon < 0) {
                return null;
            } else {
                int startQuote = json.indexOf(34, colon + 1);
                if (startQuote < 0) {
                    return null;
                } else {
                    int endQuote = json.indexOf(34, startQuote + 1);
                    return endQuote < 0 ? null : json.substring(startQuote + 1, endQuote);
                }
            }
        }
    }
}
