import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
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.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Locale;

/**
 * Bagian 3: server dengan penyimpanan berkas. Babak 1 menulis data lewat
 * server pertama, lalu babak 2 membuat server baru atas berkas yang sama
 * untuk membuktikan data bertahan melewati "restart".
 */
public class ServerApi {

    public static void main(String[] args) throws Exception {
        Path berkas = Path.of("tugas-api.txt");

        System.out.println("=== Babak 1: server pertama menulis ke berkas ===");
        HttpServer server1 = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0);
        server1.createContext("/", new RouterTugas(new RepositoryBerkas(berkas)));
        server1.start();
        String dasar1 = "http://127.0.0.1:" + server1.getAddress().getPort();
        HttpClient klien1 = HttpClient.newHttpClient();
        try {
            cetak(klien1, "POST", dasar1 + "/api/tugas",
                    "{\"judul\":\"Belajar HttpServer\",\"pemilik\":\"Budi\",\"tenggat\":\"2026-01-20\"}",
                    null);
            cetak(klien1, "POST", dasar1 + "/api/tugas",
                    "{\"judul\":\"Tulis dokumentasi API\",\"pemilik\":\"Siti\",\"tenggat\":\"2026-02-01\"}",
                    null);
            cetak(klien1, "PUT", dasar1 + "/api/tugas/1",
                    "{\"judul\":\"Belajar HttpServer\",\"pemilik\":\"Budi\","
                            + "\"status\":\"SELESAI\",\"tenggat\":\"2026-01-20\"}",
                    null);
            cetak(klien1, "POST", dasar1 + "/api/tugas",
                    "{\"pemilik\":\"Dewi\",\"tenggat\":\"20-01-2026\"}",
                    "dua field bermasalah");
        } finally {
            server1.stop(0);
        }

        System.out.println();
        System.out.println("=== Isi tugas-api.txt setelah server berhenti ===");
        System.out.print(Files.readString(berkas, StandardCharsets.UTF_8));

        System.out.println();
        System.out.println("=== Babak 2: server baru memuat ulang berkas ===");
        HttpServer server2 = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0);
        server2.createContext("/", new RouterTugas(new RepositoryBerkas(berkas)));
        server2.start();
        String dasar2 = "http://127.0.0.1:" + server2.getAddress().getPort();
        HttpClient klien2 = HttpClient.newHttpClient();   // klien segar: koneksi lama tidak berlaku lagi
        try {
            cetak(klien2, "GET", dasar2 + "/api/tugas", null, null);
            cetak(klien2, "POST", dasar2 + "/api/tugas",
                    "{\"judul\":\"Rapat tim mingguan\",\"pemilik\":\"Dewi\",\"tenggat\":\"2026-02-10\"}",
                    null);
            cetak(klien2, "POST", dasar2 + "/api/tugas",
                    "{\"judul\":\"Rapat;belanja bulanan\",\"pemilik\":\"Dewi\",\"tenggat\":\"2026-02-15\"}",
                    "memuat pemisah ;");
        } finally {
            server2.stop(0);
        }
    }

    /**
     * Mengirim satu permintaan lalu mencetak status dan body responsnya.
     * Nomor port sengaja tidak dicetak agar keluaran tetap deterministik.
     */
    private static void cetak(HttpClient klien, String metode, String url,
            String body, String keterangan) throws IOException, InterruptedException {
        HttpRequest.Builder b = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(5));
        if (body == null) {
            b.method(metode, HttpRequest.BodyPublishers.noBody());
        } else {
            b.header("Content-Type", "application/json")
                    .method(metode, HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8));
        }
        HttpResponse<String> respons =
                klien.send(b.build(), HttpResponse.BodyHandlers.ofString());

        String path = URI.create(url).getPath();
        String target = keterangan == null ? path : path + " (" + keterangan + ")";
        System.out.printf(Locale.US, "%-6s %-30s -> %d %s%n",
                metode, target, respons.statusCode(), respons.body());
    }
}
