package main

// Kurulu eklenti kayitlari (bridge-kurulu.json). Chrome'daki gibi: kurulu ama devre disi olabilir.
// Devre disi birakilan eklentinin tum site yetkileri dusurulur; yeniden acmak icin onay gerekir.
// Bu dosya indirme/calistirma yapmaz; yalnizca durumu tutar. Liste her profil icin ayridir.

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

type kuruluEklenti struct {
	Anahtar string `json:"anahtar"`
	Surum   string `json:"surum"`
	Etkin   bool   `json:"etkin"`
	// Acilista: yalnizca imzali manifest bunu istediyse ve kullanici kurulumda onayladiysa true.
	Acilista bool `json:"acilista"`
}

var (
	kuruluMu sync.Mutex
	// kuruluListeler: profil anahtarina gore kurulu eklentiler. Bos anahtar: profil secilmemis (kok klasor).
	kuruluListeler = map[string][]kuruluEklenti{}
	errKuruluYok   = errors.New("eklenti kurulu degil")
)

// kuruluListeAl: anahtarin kurulu listesi. kuruluMu kilitliyken cagrilmali.
func kuruluListeAl(anahtar string) []kuruluEklenti {
	return kuruluListeler[anahtar]
}

// kuruluDosyasi: verilen profilin kurulu listesi dosyasi. Bos anahtar: kok klasor.
func kuruluDosyasi(anahtar string) (string, error) {
	var klasor string
	var err error
	if anahtar == "" {
		klasor, err = veriKlasoru()
	} else {
		klasor, err = profilKlasoru(anahtar)
	}
	if err != nil {
		return "", err
	}
	return filepath.Join(klasor, "bridge-kurulu.json"), nil
}

// kuruluYukleProfil: verilen profilin kurulu listesini diskten okur. Dosya yoksa liste bos.
func kuruluYukleProfil(anahtar string) error {
	yol, err := kuruluDosyasi(anahtar)
	if err != nil {
		return err
	}
	veri, err := os.ReadFile(yol)
	if errors.Is(err, os.ErrNotExist) {
		kuruluMu.Lock()
		kuruluListeler[anahtar] = nil
		kuruluMu.Unlock()
		return nil
	}
	if err != nil {
		return err
	}
	var liste []kuruluEklenti
	if err := json.Unmarshal(veri, &liste); err != nil {
		return err
	}
	kuruluMu.Lock()
	kuruluListeler[anahtar] = liste
	kuruluMu.Unlock()
	return nil
}

// kuruluKaydetLocked: anahtarin listesini diske yazar. kuruluMu kilitliyken cagrilmali.
func kuruluKaydetLocked(anahtar string) error {
	yol, err := kuruluDosyasi(anahtar)
	if err != nil {
		return err
	}
	liste := kuruluListeler[anahtar]
	if liste == nil {
		liste = []kuruluEklenti{}
	}
	veri, err := json.MarshalIndent(liste, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(yol, veri, 0o600)
}

// kuruluEkleProfil: verilen profilin kurulu listesine ekler (ayni anahtar varsa gunceller).
func kuruluEkleProfil(profil string, k kuruluEklenti) error {
	kuruluMu.Lock()
	defer kuruluMu.Unlock()
	anahtar := profil
	mevcut := kuruluListeAl(anahtar)
	kalan := make([]kuruluEklenti, 0, len(mevcut)+1)
	for _, m := range mevcut {
		if m.Anahtar != k.Anahtar {
			kalan = append(kalan, m)
		}
	}
	kuruluListeler[anahtar] = append(kalan, k)
	return kuruluKaydetLocked(anahtar)
}

// kuruluKaldirProfil: verilen profilin kurulu listesinden kaydi siler.
func kuruluKaldirProfil(profil, anahtar string) error {
	kuruluMu.Lock()
	defer kuruluMu.Unlock()
	mevcut := kuruluListeAl(profil)
	kalan := make([]kuruluEklenti, 0, len(mevcut))
	bulundu := false
	for _, m := range mevcut {
		if m.Anahtar == anahtar {
			bulundu = true
			continue
		}
		kalan = append(kalan, m)
	}
	if !bulundu {
		return errKuruluYok
	}
	kuruluListeler[profil] = kalan
	return kuruluKaydetLocked(profil)
}

// kuruluEtkinAyarlaProfil: verilen profilde etkinlestirir/devre disi birakir.
func kuruluEtkinAyarlaProfil(profil, anahtar string, etkin bool) error {
	kuruluMu.Lock()
	bulundu := false
	liste := kuruluListeAl(profil)
	for i := range liste {
		if liste[i].Anahtar == anahtar {
			liste[i].Etkin = etkin
			bulundu = true
		}
	}
	if !bulundu {
		kuruluMu.Unlock()
		return errKuruluYok
	}
	err := kuruluKaydetLocked(profil)
	kuruluMu.Unlock()
	if err != nil {
		return err
	}
	if !etkin {
		// Kilit disinda: yetki modulu kendi kilidini alir.
		return yetkiGeriAlProfil(profil, anahtar, "")
	}
	return nil
}

// kuruluAcilistaAyarlaProfil: verilen profilde acilis tercihini kaydeder. Yalnizca kullanici onayiyla.
func kuruluAcilistaAyarlaProfil(profil, anahtar string, acilista bool) error {
	kuruluMu.Lock()
	defer kuruluMu.Unlock()
	liste := kuruluListeAl(profil)
	for i := range liste {
		if liste[i].Anahtar == anahtar {
			liste[i].Acilista = acilista
			return kuruluKaydetLocked(profil)
		}
	}
	return errKuruluYok
}

// kuruluSurumProfil: verilen profilde kurulu surum ve var mi bilgisi.
func kuruluSurumProfil(profil, anahtar string) (string, bool) {
	kuruluMu.Lock()
	defer kuruluMu.Unlock()
	for _, k := range kuruluListeAl(profil) {
		if k.Anahtar == anahtar {
			return k.Surum, true
		}
	}
	return "", false
}
