import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicInteger;

public class KlienRetry {
    public static void main(String[] args) throws Exception {
        // Penghitung panggilan: dua kegagalan pertama disengaja
        AtomicInteger panggilan = new AtomicInteger(0);
        HttpServer server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0);
        server.createContext("/tugas", exchange -> {
            int nomor = panggilan.incrementAndGet();
            if (nomor <= 2) {
                exchange.sendResponseHeaders(503, -1);
                exchange.close();
            } else {
                byte[] body = "tugas diterima".getBytes(StandardCharsets.UTF_8);
                exchange.sendResponseHeaders(200, body.length);
                try (OutputStream os = exchange.getResponseBody()) {
                    os.write(body);
                }
            }
        });
        server.start();

        try {
            HttpClient klien = HttpClient.newHttpClient();
            HttpRequest req = HttpRequest.newBuilder()
                    .uri(URI.create("http://127.0.0.1:" + server.getAddress().getPort() + "/tugas"))
                    .GET()
                    .build();

            int maksCoba = 4;
            for (int coba = 1; coba <= maksCoba; coba++) {
                try {
                    HttpResponse<String> res = klien.send(req,
                            HttpResponse.BodyHandlers.ofString());
                    System.out.println("percobaan " + coba + ": status " + res.statusCode());
                    if (res.statusCode() / 100 == 2) {
                        System.out.println("body      : " + res.body());
                        break;
                    }
                } catch (IOException e) {
                    System.out.println("percobaan " + coba + ": galat "
                            + e.getClass().getSimpleName());
                }
                if (coba < maksCoba) {
                    long jeda = 100L * (1L << (coba - 1)); // 100 lalu 200 ms
                    Thread.sleep(jeda);
                    System.out.println("jeda      : " + jeda + " ms lalu coba lagi");
                }
            }
        } finally {
            server.stop(0);
        }
    }
}
