package main

// fikoyt-eklenti-usb: USB surucu takma/cikarma bildirimi (surekli calisan eklenti).
// Protokol: stdin'den satir bazli JSON komutu, stdout'a satir bazli JSON mesajlari.
//   komutlar: {"islem":"ping"} -> cevap; {"islem":"ayar","veri":{...}} -> ayarlari guncelle;
//             {"islem":"cik"} -> cikis. Ilk mesaj her zaman "durum" olur.
//   mesajlar: durum | olay | cevap | hata

import (
	"bufio"
	"context"
	"encoding/json"
	"os"
	"sync"
)

type komut struct {
	Islem string          `json:"islem"`
	Veri  json.RawMessage `json:"veri,omitempty"`
}

func main() {
	var yazMu sync.Mutex
	kodlayici := json.NewEncoder(os.Stdout)
	yaz := func(m Mesaj) {
		yazMu.Lock()
		defer yazMu.Unlock()
		_ = kodlayici.Encode(m)
	}

	var ayarMu sync.Mutex
	ayar := varsayilanAyar()
	ayarAl := func() Ayar {
		ayarMu.Lock()
		defer ayarMu.Unlock()
		return ayar
	}

	// Olay dinleyicisi: takma/cikarma bildirimi gelince tetik gonderir (bloklamaz).
	tetik := make(chan struct{}, 1)
	if err := dinleyiciBaslat(func() {
		select {
		case tetik <- struct{}{}:
		default:
		}
	}); err != nil {
		yaz(Mesaj{Tip: "hata", Hata: err.Error()})
		os.Exit(1)
	}

	ctx, iptal := context.WithCancel(context.Background())
	defer iptal()

	// Baslangic durumu gonderilmeden stdin okunmaz; cikista mesaj kaybolmaz.
	durumHazir := make(chan struct{})
	var bir sync.Once
	yazDurum := func(m Mesaj) {
		yaz(m)
		if m.Tip == "durum" {
			bir.Do(func() { close(durumHazir) })
		}
	}
	go izle(ctx, taraSuruculer, yazDurum, tetik, ayarAl)
	<-durumHazir

	okuyucu := bufio.NewScanner(os.Stdin)
	okuyucu.Buffer(make([]byte, 16*1024), 16*1024)
	for okuyucu.Scan() {
		var k komut
		if err := json.Unmarshal(okuyucu.Bytes(), &k); err != nil {
			continue
		}
		switch k.Islem {
		case "ping":
			yaz(Mesaj{Tip: "cevap", Tamam: true})
		case "tara":
			// Istek uzerine mevcut surucu listesini yeniden yollar (web detay sayfasi acilinca kullanir).
			liste, err := taraSuruculer()
			if err != nil {
				yaz(Mesaj{Tip: "hata", Hata: "sürücüler okunamadı"})
				break
			}
			yaz(Mesaj{Tip: "durum", Suruculer: liste})
		case "ayar":
			ayarMu.Lock()
			yeni := ayar
			err := json.Unmarshal(k.Veri, &yeni)
			if err == nil {
				ayar = yeni
			}
			ayarMu.Unlock()
			yaz(Mesaj{Tip: "cevap", Tamam: err == nil})
		case "cik":
			return
		}
	}
	// stdin kapandi: bridge surecu durdurdu ya da baglanti koptu.
}
