import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

public class ProsesBatch {
    static final int UKURAN_BATCH = 5;
    static final Path CHECKPOINT = Path.of("checkpoint.txt");

    public static void main(String[] args) throws IOException {
        List<String> baris = Files.readAllLines(Path.of("transaksi.txt"),
                StandardCharsets.UTF_8);
        System.out.println("total baris masukan: " + baris.size());

        // Fase 1: kegagalan disimulasikan menghentikan proses di batch ke-3.
        System.out.println("== proses pertama ==");
        jalankan(baris, false);
        System.out.println("posisi aman : " + bacaCheckpoint() + " dari " + baris.size());

        // Fase 2: program dijalankan ulang; checkpoint menentukan titik lanjut.
        System.out.println("== proses ulang ==");
        jalankan(baris, true);
        System.out.println("posisi aman : " + bacaCheckpoint() + " dari " + baris.size());

        long total = baris.stream().mapToLong(ProsesBatch::nilai).sum();
        System.out.println("total nilai : " + total);
    }

    static void jalankan(List<String> baris, boolean faseUlang) throws IOException {
        int posisi = bacaCheckpoint();          // titik lanjut terakhir yang sah
        if (posisi > 0) {
            System.out.println("melanjutkan dari baris " + (posisi + 1));
        }
        while (posisi < baris.size()) {
            int batchKe = posisi / UKURAN_BATCH + 1;
            int awal = posisi;
            int akhir = Math.min(awal + UKURAN_BATCH, baris.size());

            // Kegagalan disimulasikan hanya pada proses pertama, batch ke-3.
            if (!faseUlang && batchKe == 3) {
                System.out.println("batch " + batchKe + ": baris " + (awal + 1)
                        + "-" + akhir + " -- GAGAL: kegagalan disimulasikan");
                return;                          // checkpoint batch ini tidak ditulis
            }

            long nilaiBatch = 0;
            for (int i = awal; i < akhir; i++) {
                nilaiBatch += nilai(baris.get(i));
            }
            posisi = akhir;
            tulisCheckpoint(posisi);             // ditulis SETELAH batch selesai
            System.out.println("batch " + batchKe + ": baris " + (awal + 1) + "-" + akhir
                    + " nilai=" + nilaiBatch + " (checkpoint: " + posisi + ")");
        }
    }

    static long nilai(String baris) {
        return Long.parseLong(baris.split(",")[2]);
    }

    static int bacaCheckpoint() throws IOException {
        if (!Files.exists(CHECKPOINT)) {
            return 0;
        }
        return Integer.parseInt(Files.readString(CHECKPOINT).trim());
    }

    static void tulisCheckpoint(int posisi) throws IOException {
        Files.writeString(CHECKPOINT, Integer.toString(posisi));
    }
}
