package main

import (
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
)

// izinIsteCagir: verilen token ile /izin-iste isleyicisine POST atar; kodu dondurur.
func izinIsteCagir(t *testing.T, token, anahtar string) int {
	t.Helper()
	h := korumali(izinIsteHandler)
	req := httptest.NewRequest(http.MethodPost, "/izin-iste", strings.NewReader(`{"anahtar":"`+anahtar+`"}`))
	req.Header.Set("X-Bridge-Token", token)
	req.Header.Set("Content-Type", "application/json")
	rec := httptest.NewRecorder()
	h(rec, req)
	return rec.Code
}

// izinIsteKurulum: iki etkin hesap, temiz izin durumu, onay ekrani taklidi (karar: onay).
func izinIsteKurulum(t *testing.T, karar bool) {
	t.Helper()
	t.Setenv("APPDATA", t.TempDir())
	profilTokenKur(t, "ahmet", "t-ahmet")
	profilTokenKur(t, "ayse", "t-ayse")
	etkinTestKur(t, "ahmet", "ayse")
	for _, p := range []string{"ahmet", "ayse"} {
		if err := izinleriKaydetProfil(p, Izinler{}); err != nil {
			t.Fatal(err)
		}
		// Site yetkileri de bellekte kalabilir; temiz baslamak icin geri al.
		if err := yetkiGeriAlProfil(p, "everythingAra", tokenOzeti("t-ayse")); err != nil {
			t.Fatal(err)
		}
	}
	eski := onayBekle
	onayBekle = func(baslik, aciklama string) (bool, error) { return karar, nil }
	t.Cleanup(func() { onayBekle = eski })
}

// TestIzinIsteProfilIzole: onay verilince izin yalnizca isteğin hesabina yazilir; diger hesap etkilenmez.
func TestIzinIsteProfilIzole(t *testing.T) {
	izinIsteKurulum(t, true)

	if c := izinIsteCagir(t, "t-ayse", "everythingAra"); c != http.StatusOK {
		t.Fatalf("ayse izin-iste 200 bekleniyordu, %d", c)
	}
	if !izinOkuProfil("ayse").EverythingAra {
		t.Errorf("ayse'nin izni acilmaliydi")
	}
	if izinOkuProfil("ahmet").EverythingAra {
		t.Errorf("ahmet'in izni acilmamaliydi")
	}
	if !yetkiGecerliMiProfil("ayse", "everythingAra", tokenOzeti("t-ayse")) {
		t.Errorf("ayse icin site yetkisi verilmeliydi")
	}
	if yetkiGecerliMiProfil("ahmet", "everythingAra", tokenOzeti("t-ayse")) {
		t.Errorf("ahmet'in hesabinda ayse'nin site yetkisi olmamali")
	}
}

// TestIzinIsteBaslikHesapAdi: onay penceresi basligi, izni isteyen hesabin adini icerir.
func TestIzinIsteBaslikHesapAdi(t *testing.T) {
	izinIsteKurulum(t, true)
	var gorunen string
	eski := onayBekle
	onayBekle = func(baslik, aciklama string) (bool, error) {
		gorunen = baslik
		return true, nil
	}
	t.Cleanup(func() { onayBekle = eski })

	if c := izinIsteCagir(t, "t-ayse", "everythingAra"); c != http.StatusOK {
		t.Fatalf("izin-iste 200 bekleniyordu, %d", c)
	}
	if !strings.Contains(gorunen, "ayse") || strings.Contains(gorunen, "ahmet") {
		t.Errorf("baslik ayse'yi icermeli, ahmet'i icermemeli: %q", gorunen)
	}
}

// TestIzinIsteReddedilince: kullanici reddederse hicbir hesapta izin veya yetki olusmaz.
func TestIzinIsteReddedilince(t *testing.T) {
	izinIsteKurulum(t, false)

	if c := izinIsteCagir(t, "t-ayse", "everythingAra"); c != http.StatusForbidden {
		t.Fatalf("reddedilince 403 bekleniyordu, %d", c)
	}
	if izinOkuProfil("ayse").EverythingAra {
		t.Errorf("reddedilen izin kaydedilmemeliydi")
	}
	if yetkiGecerliMiProfil("ayse", "everythingAra", tokenOzeti("t-ayse")) {
		t.Errorf("reddedilen istekte site yetkisi olusmamaliydi")
	}
}
