package main

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

// Izinler: her yetki ayri onaylanir ve varsayilan KAPALIDIR.
// Izin degisikligi yalnizca yerel tepsi arayuzunden yapilir (bu dosyada web'den
// yazan uc YOKTUR).
type Izinler struct {
	EverythingAra      bool  `json:"everythingAra"`
	CatiaAc            bool  `json:"catiaAc"`
	UsbBaglanti        bool  `json:"usbBaglanti"`
	DosyaYonetimiBitis int64 `json:"dosyaYonetimiBitis"`
}

var (
	izinMu sync.RWMutex
	izin   Izinler
)

func izinDosyasi() (string, error) {
	klasor, err := veriKlasoru()
	if err != nil {
		return "", err
	}
	return filepath.Join(klasor, "bridge-izin.json"), nil
}

func izinleriYukle() error {
	yol, err := izinDosyasi()
	if err != nil {
		return err
	}
	veri, err := os.ReadFile(yol)
	if errors.Is(err, os.ErrNotExist) {
		return nil // varsayilan: hepsi kapali
	}
	if err != nil {
		return err
	}
	var y Izinler
	if err := json.Unmarshal(veri, &y); err != nil {
		return err
	}
	izinMu.Lock()
	izin = y
	izinMu.Unlock()
	return nil
}

func izinleriKaydet(y Izinler) error {
	yol, err := izinDosyasi()
	if err != nil {
		return err
	}
	veri, err := json.MarshalIndent(y, "", "  ")
	if err != nil {
		return err
	}
	izinMu.Lock()
	izin = y
	izinMu.Unlock()
	return os.WriteFile(yol, veri, 0o600)
}

func izinOku() Izinler {
	izinMu.RLock()
	defer izinMu.RUnlock()
	return izin
}

// izinlerHandler: yalnizca okuma. Degisiklik tepsi arayuzunden yapilir.
func izinlerHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "yalnizca GET", http.StatusMethodNotAllowed)
		return
	}
	yazJSON(w, http.StatusOK, izinOku())
}

// Acik: anahtara gore izin durumu. Bilinmeyen anahtar kapali sayilir.
func (y Izinler) Acik(anahtar string) bool {
	switch anahtar {
	case "everythingAra":
		return y.EverythingAra
	case "catiaAc":
		return y.CatiaAc
	case "usb":
		return y.UsbBaglanti
	case "dosyaYonetimi":
		return y.DosyaYonetimiBitis > time.Now().Unix()
	}
	return false
}

// Ayarla: anahtarin izin degerini degistirir (bilinmeyen anahtar yok sayilir).
// dosyaYonetimi icin true kalici (yaklasik 100 yil) olarak kaydedilir; sureli izin izinOnayla/izinKaydetOnay ile yazilir.
func (y *Izinler) Ayarla(anahtar string, deger bool) {
	switch anahtar {
	case "everythingAra":
		y.EverythingAra = deger
	case "catiaAc":
		y.CatiaAc = deger
	case "usb":
		y.UsbBaglanti = deger
	case "dosyaYonetimi":
		if deger {
			y.DosyaYonetimiBitis = time.Now().Add(kaliciSure).Unix()
		} else {
			y.DosyaYonetimiBitis = 0
		}
	}
}

// izinOnayla: yerel onay ekranini acar. dosyaYonetimi secenekli (sure secilir); digerleri iki dugmeli.
func izinOnayla(anahtar, baslik, aciklama string) (bool, string, error) {
	if anahtar == "dosyaYonetimi" {
		return onayBekleSecenekli(onayBilgi{baslik: baslik, aciklama: aciklama})
	}
	onay, err := onayBekle(baslik, aciklama)
	return onay, sureBuSefer, err
}

// izinKaydetOnay: onaylanan izni kaydeder. dosyaYonetimi icin "bu sefer" kalici kayit yapmaz (false doner).
func izinKaydetOnay(anahtar, sure string) (bool, error) {
	y := izinOku()
	if anahtar == "dosyaYonetimi" {
		bitis, ok := secimBitisi(sure, time.Now())
		if !ok {
			return false, nil
		}
		y.DosyaYonetimiBitis = bitis
	} else {
		y.Ayarla(anahtar, true)
	}
	if err := izinleriKaydet(y); err != nil {
		return false, err
	}
	olayLog("izin yerelde onaylandı: %s (%s)", anahtar, sure)
	izinDurumGonder()
	return true, nil
}
