/* tests.c -- rangkaian test untuk modul contact dan storage. */

#include "contact.h"
#include "storage.h"

#include <stdio.h>
#include <string.h>

static int lulus = 0;
static int gagal = 0;

#define PERIKSA(kondisi, nama)                              \
    do {                                                    \
        if (kondisi) { lulus++; printf("[LULUS] %s\n", nama); } \
        else { gagal++; printf("[GAGAL] %s\n", nama); }     \
    } while (0)

static void test_tambah_dan_tampilkan(void) {
    ContactList list;
    contact_list_init(&list);
    ContactStatus s1 = contact_tambah(&list, "Budi", "0811", "budi@example.com");
    ContactStatus s2 = contact_tambah(&list, "Siti", "0812", "siti@example.com");
    PERIKSA(s1 == CONTACT_OK && s2 == CONTACT_OK, "Tambah 2 kontak berhasil");
    PERIKSA(list.jumlah == 2, "Jumlah = 2 setelah tambah");
    PERIKSA(list.data[0].id == 1 && list.data[1].id == 2,
           "ID auto-increment 1, 2");
}

static void test_tambah_nama_kosong(void) {
    ContactList list;
    contact_list_init(&list);
    ContactStatus s = contact_tambah(&list, "", "0811", "x@example.com");
    PERIKSA(s == CONTACT_ERR_INPUT_INVALID, "Nama kosong ditolak");
    PERIKSA(list.jumlah == 0, "Tidak ada kontak ditambahkan");
}

static void test_cari(void) {
    ContactList list;
    contact_list_init(&list);
    contact_tambah(&list, "Budi", "0811", "budi@example.com");
    contact_tambah(&list, "Siti", "0812", "siti@example.com");
    int idx = contact_cari(&list, "Siti");
    PERIKSA(idx == 1, "Cari 'Siti' -> indeks 1");
    PERIKSA(contact_cari(&list, "Tidak Ada") == -1, "Cari nama tidak ada -> -1");
}

static void test_ubah(void) {
    ContactList list;
    contact_list_init(&list);
    contact_tambah(&list, "Budi", "0811", "budi@example.com");
    ContactStatus s = contact_ubah(&list, 1, "Budi Santoso", 0, 0);
    PERIKSA(s == CONTACT_OK, "Ubah kontak id=1 berhasil");
    PERIKSA(strcmp(list.data[0].nama, "Budi Santoso") == 0,
           "Nama berubah menjadi 'Budi Santoso'");
    PERIKSA(strcmp(list.data[0].telp, "0811") == 0,
           "Telp tetap '0811' (tidak diubah)");
}

static void test_hapus(void) {
    ContactList list;
    contact_list_init(&list);
    contact_tambah(&list, "Budi", "0811", "budi@example.com");
    contact_tambah(&list, "Siti", "0812", "siti@example.com");
    contact_tambah(&list, "Andi", "0813", "andi@example.com");
    ContactStatus s = contact_hapus(&list, 2);
    PERIKSA(s == CONTACT_OK, "Hapus id=2 berhasil");
    PERIKSA(list.jumlah == 2, "Jumlah = 2 setelah hapus");
    PERIKSA(strcmp(list.data[1].nama, "Andi") == 0,
           "Setelah hapus, elemen 1 = 'Andi'");
    PERIKSA(contact_hapus(&list, 999) == CONTACT_ERR_TIDAK_DITEMUKAN,
           "Hapus id tidak ada -> error");
}

static void test_penyimpanan(void) {
    ContactList list;
    contact_list_init(&list);
    contact_tambah(&list, "Budi", "0811", "budi@example.com");
    contact_tambah(&list, "Siti", "0812", "siti@example.com");

    StorageStatus ss = storage_simpan(&list, "/tmp/test_kontak.txt");
    PERIKSA(ss == STORAGE_OK, "Simpan ke /tmp/test_kontak.txt");

    ContactList dimuat;
    contact_list_init(&dimuat);
    ss = storage_muat(&dimuat, "/tmp/test_kontak.txt");
    PERIKSA(ss == STORAGE_OK, "Muat dari /tmp/test_kontak.txt");
    PERIKSA(dimuat.jumlah == 2, "Jumlah dimuat = 2");
    PERIKSA(strcmp(dimuat.data[0].nama, "Budi") == 0,
           "Kontak pertama dimuat: 'Budi'");
    PERIKSA(dimuat.id_berikutnya == 3,
           "id_berikutnya = 3 setelah muat");
}

int main(void) {
    test_tambah_dan_tampilkan();
    test_tambah_nama_kosong();
    test_cari();
    test_ubah();
    test_hapus();
    test_penyimpanan();
    printf("\nRingkasan: %d lulus, %d gagal\n", lulus, gagal);
    return gagal == 0 ? 0 : 1;
}
