import sys
sys.path.insert(0, r'D:\__sistem__\Masaustu\FikoYT.Yeni.Cag\_yama_tmp')
from yama_lib import *

S = r'D:\__sistem__\Masaustu\FikoYT.Yeni.Cag\docker\fikoyt-sunucu\merkez.go-server.com'

# ---------------------------------------------------------------- socket_ortak.go
P = S + r'\sistem\socket_ortak\socket_ortak.go'
yedekle(P)
t, crlf = oku(P)
t = t.rstrip('\n') + '\n' + r'''
// CihazaKomutGonder, "FikoYT.sistem.io.cihaz.komut" olayini YALNIZ cihaz_kimlik'i eslesen
// soket(ler)e yollar ve hedef soket sayisini dondurur (0 = cihaz bagli degil).
// Gercek uygulama fikoyt_socket_io.Ayarla icinde atanir; fonksiyon degiskeni olmasinin
// nedeni import dongusudur (fikoyt_socket_io -> uyar; uyar ve lisans_kontrol,
// fikoyt_socket_io'yu import edemez). Atama oncesi nil'dir.
var CihazaKomutGonder func(cihazKimlik string, komut map[string]interface{}) int
'''
yaz(P, t, crlf)

# ---------------------------------------------------------------- fiko_socket_io.go
P = S + r'\sistem\fikoyt_socket_io\fiko_socket_io.go'
yedekle(P)
t, crlf = oku(P)

t = degistir(t,
'''	socket_ortak.FikoSocketIo = socket.NewServer(nil, socketioSettings)
''',
'''	socket_ortak.FikoSocketIo = socket.NewServer(nil, socketioSettings)
	// Hedefli komut yonlendirmesi: tetikleyici motoru ve lisans paneli de bunu kullanir.
	socket_ortak.CihazaKomutGonder = cihazaKomutGonder
''')

HELPER = r'''// cihazaKomutGonder, "FikoYT.sistem.io.cihaz.komut" olayini YALNIZ cihaz_kimlik'i eslesen
// soket(ler)e yollar. Uc kaynak da (admin soket olayi, tetikleyici motoru, lisans paneli
// POST /komut) bu tek yolu kullanir. Donus: hedef soket sayisi (0 = cihaz bagli degil).
// Cihaz yeniden baglanirken eski soket bir sure haritada kalabilir; bu yuzden ilk eslesmeyle
// yetinilmez, eslesen HEPSINE gonderilir (olu soket zaten hicbir sey almaz).
func cihazaKomutGonder(cihazKimlik string, komut map[string]interface{}) int {
	if socket_ortak.FikoSocketIo == nil || cihazKimlik == "" {
		return 0
	}
	hedefler := make(map[string]struct{})
	soketCihazMapMu.RLock()
	for sid, ck := range soketCihazMap {
		if ck == cihazKimlik {
			hedefler[sid] = struct{}{}
		}
	}
	soketCihazMapMu.RUnlock()
	if len(hedefler) == 0 {
		return 0
	}
	socket_ortak.FikoSocketIo.FetchSockets()(func(sockets []*socket.RemoteSocket, err error) {
		if err != nil {
			log.Printf("Komut gonderimi: FetchSockets hatasi: %v", err)
			return
		}
		for _, s := range sockets {
			if _, hedef := hedefler[string(s.Id())]; hedef {
				s.Emit("FikoYT.sistem.io.cihaz.komut", komut)
			}
		}
	})
	return len(hedefler)
}

'''
t = degistir(t, '// hasKey kontrol fonksiyonu\n', HELPER + '// hasKey kontrol fonksiyonu\n')

HANDLER = r'''	// Uzak komut: admin panelden belirli cihaza komut ilet
	client.On("FikoYT.sistem.io.cihaz.komut", func(args ...interface{}) {
		if len(args) < 1 {
			return
		}
		data, ok := args[0].(map[string]interface{})
		if !ok {
			return
		}
		hedefCihazKimlik, _ := data["cihaz_kimlik"].(string)
		if hedefCihazKimlik == "" {
			return
		}

		// Hedefli gonderim: tetikleyici motoru ve lisans paneli ile AYNI yol.
		if n := cihazaKomutGonder(hedefCihazKimlik, data); n > 0 {
			log.Printf("Komut gonderildi: %s -> %s (komut: %v, soket: %d)", string(client.Id()), hedefCihazKimlik, data["komut_kodu"], n)
		} else {
			log.Printf("Komut hedefi bulunamadi: %s", hedefCihazKimlik)
		}
	})

'''
t = aralik_degistir(t,
    '// Uzak komut: admin panelden belirli cihaza komut ilet',
    "// Cihaz olay kaydi: cihazlardan gelen olaylari DB'ye kaydet + broadcast",
    HANDLER)
yaz(P, t, crlf)

# ---------------------------------------------------------------- tetikleyici_motor.go
P = S + r'\apps\uyar_dokum\uyar\tetikleyici_motor.go'
yedekle(P)
t, crlf = oku(P)
t = degistir(t,
'''	socket_ortak.FikoSocketIo.FetchSockets()(func(sockets []*socket.RemoteSocket, err error) {
		if err != nil {
			return
		}
		for _, s := range sockets {
			s.Emit("FikoYT.sistem.io.cihaz.komut", komutData)
		}
	})
}
''',
'''	// HEDEFLI gonderim: yalniz cihaz_kimlik'i eslesen soket(ler) alir. Eskiden komut TUM
	// soketlere yayinlaniyordu (her cihaz ve her admin paneli komutu goruyordu) ve
	// fiko_socket_io.go'daki hedefli yoldan sapiyordu.
	if socket_ortak.CihazaKomutGonder == nil {
		log.Printf("[TetikleyiciMotor] Cihaz komutu gonderilemedi: soket katmani hazir degil (kural: %s)", kural.Ad)
		return
	}
	if komutKodu == "" || komutId == "" || imza == "" {
		log.Printf("[TetikleyiciMotor] UYARI: komut eksik alanli (komut_kodu=%q komutId=%q imza_var=%v, kural: %s) - cihaz REDDEDECEK",
			komutKodu, komutId, imza != "", kural.Ad)
	}
	if n := socket_ortak.CihazaKomutGonder(hedefCihaz, komutData); n > 0 {
		log.Printf("Komut gonderildi: tetikleyici -> %s (komut: %s, kural: %s, komutId: %s, soket: %d)", hedefCihaz, komutKodu, kural.Ad, komutId, n)
	} else {
		log.Printf("[TetikleyiciMotor] Komut hedefi bagli degil: %s (kural: %s)", hedefCihaz, kural.Ad)
	}
}
''')
# artik kullanilmayan import
t = degistir(t, '\t"github.com/zishang520/socket.io/v2/socket"\n', '')
yaz(P, t, crlf)

# ---------------------------------------------------------------- lisans_kontrol.go
P = S + r'\apps\lisans_kontrol\lisans_kontrol.go'
yedekle(P)
t, crlf = oku(P)
t = degistir(t,
'''	fiko_mongo "server/sistem/fikoyt_mongo"
''',
'''	fiko_mongo "server/sistem/fikoyt_mongo"
	socket_ortak "server/sistem/socket_ortak"
''')

t = degistir(t,
'''func uzakKomutGonder(kimlik string, komut map[string]interface{}) error {
''',
'''func uzakKomutGonder(kimlik string, komut map[string]interface{}) error {
	// Canli cihazlar genel /socket.io/ sunucusuna (fikoyt_socket_io, main.go:51) baglanir.
	// Bu dosyadaki FikoUzakSocketIo ayni yolu (/socket.io/) main.go:57'de SONRA kaydeder;
	// Fiber ilk kayitli rotayi calistirdigi icin o sunucu hic trafik almaz ve uzakCihazlar
	// bos kalir. Bu yuzden once canli yola (soketCihazMap) gonderilir; eski yol yedek.
	if socket_ortak.CihazaKomutGonder != nil {
		if n := socket_ortak.CihazaKomutGonder(kimlik, komut); n > 0 {
			return nil
		}
	}
''')

t = degistir(t,
'''		kanonik := "komutId=" + komutId + "\\n" +
			"komut_kodu=" + tip + "\\n" +''',
'''		// Istemci komutu "komut_kodu" alanindan okur ve imzayi bu degerle dogrular; govdede
		// yalniz "tip" varsa komut_kodu BOS gider ve cihaz komutu reddederdi.
		if kk, _ := komut["komut_kodu"].(string); kk == "" && tip != "" {
			komut["komut_kodu"] = tip
		}
		kanonik := "komutId=" + komutId + "\\n" +
			"komut_kodu=" + tip + "\\n" +''')
yaz(P, t, crlf)
print('go TAMAM')
