package main

import (
	"fmt"
	"testing"
)

// FakeNotifier merekam setiap panggilan Kirim sehingga test dapat
// memeriksa perilaku PendaftaranService tanpa jaringan sama sekali.
type FakeNotifier struct {
	panggilan []Pesan
	gagal     bool
}

// Kirim mencatat panggilan, atau mengembalikan galat bila mode gagal aktif.
func (f *FakeNotifier) Kirim(ke, subjek, isi string) error {
	if f.gagal {
		return fmt.Errorf("jaringan bermasalah")
	}
	f.panggilan = append(f.panggilan, Pesan{Ke: ke, Subjek: subjek, Isi: isi})
	return nil
}

func TestDaftarBerhasilMengirimNotifikasi(t *testing.T) {
	fake := &FakeNotifier{}
	layanan := NewPendaftaranService(fake)

	if err := layanan.Daftar("budi@example.com"); err != nil {
		t.Fatalf("Daftar gagal: %v", err)
	}
	if len(fake.panggilan) != 1 {
		t.Fatalf("jumlah panggilan Kirim = %d, diharapkan 1", len(fake.panggilan))
	}
	p := fake.panggilan[0]
	if p.Ke != "budi@example.com" || p.Subjek != "Selamat datang" {
		t.Errorf("isi pesan tidak sesuai: %+v", p)
	}
}

func TestDaftarEmailTidakValid(t *testing.T) {
	fake := &FakeNotifier{}
	layanan := NewPendaftaranService(fake)

	if err := layanan.Daftar("budi-tanpa-at"); err == nil {
		t.Fatal("Daftar seharusnya gagal untuk email tanpa karakter @")
	}
	if len(fake.panggilan) != 0 {
		t.Errorf("tidak boleh ada notifikasi terkirim, tercatat %d", len(fake.panggilan))
	}
}

func TestDaftarGagalKirimMeneruskanGalat(t *testing.T) {
	fake := &FakeNotifier{gagal: true}
	layanan := NewPendaftaranService(fake)

	if err := layanan.Daftar("budi@example.com"); err == nil {
		t.Fatal("galat dari Notifier seharusnya diteruskan ke pemanggil")
	}
}
