package main

// Etkin hesaplar: bu bilgisayarda ayni anda calisabilen hesaplarin kumesi.
// Tek "aktif" hesap kavrami korunur (geriye uyum); bu kume ise hangi hesaplarin
// istek kabul edebilecegini belirler. Liste etkin-hesaplar.json dosyasinda tutulur.

import (
	"context"
	"encoding/json"
	"errors"
	"net/http"
	"os"
	"path/filepath"
	"sort"
	"sync"
)

const etkinHesapDosyaAdi = "etkin-hesaplar.json"

var (
	etkinMu       sync.Mutex
	etkinKume     map[string]bool
	etkinYuklendi bool
	// Testlerde gercek kullanici klasorune yazmamak icin kullanilir.
	etkinDosyaOverride string
)

type profilAnahtariKey struct{}

// etkinDosyasi: etkin hesap listesinin dosya yolu.
func etkinDosyasi() (string, error) {
	if etkinDosyaOverride != "" {
		return etkinDosyaOverride, nil
	}
	kok, err := veriKlasoru()
	if err != nil {
		return "", err
	}
	return filepath.Join(kok, etkinHesapDosyaAdi), nil
}

// etkinYukleLocked: kume bos ve dosya okunmamissa diskten yukler. etkinMu kilitliyken cagrilmali.
func etkinYukleLocked() {
	if etkinYuklendi {
		return
	}
	etkinKume = map[string]bool{}
	etkinYuklendi = true
	yol, err := etkinDosyasi()
	if err != nil {
		return
	}
	veri, err := os.ReadFile(yol)
	if err != nil {
		return
	}
	var liste []string
	if json.Unmarshal(veri, &liste) != nil {
		return
	}
	for _, a := range liste {
		if profilAnahtarDesen.MatchString(a) {
			etkinKume[a] = true
		}
	}
}

// etkinKaydetLocked: kumeyi diske yazar. etkinMu kilitliyken cagrilmali.
func etkinKaydetLocked() error {
	yol, err := etkinDosyasi()
	if err != nil {
		return err
	}
	liste := make([]string, 0, len(etkinKume))
	for a := range etkinKume {
		liste = append(liste, a)
	}
	sort.Strings(liste)
	veri, err := json.MarshalIndent(liste, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(yol, veri, 0o600)
}

// etkinHesaplar: etkin hesap anahtarlarinin sirali listesi.
func etkinHesaplar() []string {
	etkinMu.Lock()
	defer etkinMu.Unlock()
	etkinYukleLocked()
	liste := make([]string, 0, len(etkinKume))
	for a := range etkinKume {
		liste = append(liste, a)
	}
	sort.Strings(liste)
	return liste
}

// etkinMi: verilen hesap etkin mi?
func etkinMi(anahtar string) bool {
	if anahtar == "" {
		return false
	}
	etkinMu.Lock()
	defer etkinMu.Unlock()
	etkinYukleLocked()
	return etkinKume[anahtar]
}

// etkinHesapEkle: hesabi etkin kumeye ekler ve kaydeder.
func etkinHesapEkle(anahtar string) error {
	if !profilAnahtarDesen.MatchString(anahtar) {
		return errors.New("gecersiz profil anahtari")
	}
	etkinMu.Lock()
	defer etkinMu.Unlock()
	etkinYukleLocked()
	if etkinKume[anahtar] {
		return nil
	}
	etkinKume[anahtar] = true
	return etkinKaydetLocked()
}

// etkinHesapCikar: hesabi etkin kumeden cikarir ve kaydeder. Yoksa sessizce doner.
func etkinHesapCikar(anahtar string) error {
	etkinMu.Lock()
	defer etkinMu.Unlock()
	etkinYukleLocked()
	if !etkinKume[anahtar] {
		return nil
	}
	delete(etkinKume, anahtar)
	return etkinKaydetLocked()
}

// profilBaglam: istek baglamina profil anahtarini koyar.
func profilBaglam(r *http.Request, anahtar string) *http.Request {
	return r.WithContext(context.WithValue(r.Context(), profilAnahtariKey{}, anahtar))
}

// istekProfili: istek baglamindaki profil anahtari. Yoksa bos.
func istekProfili(r *http.Request) string {
	if a, ok := r.Context().Value(profilAnahtariKey{}).(string); ok {
		return a
	}
	return ""
}

// profilDe: istegin profili. Yalnizca token baglamindan gelir; baglam yoksa bos doner.
// Yerel ayar sayfasi tek bir hesaba bagli degildir: tum etkin hesaplar arka planda aktiftir.
func profilDe(r *http.Request) string {
	return istekProfili(r)
}
