package main

// Windows Job Object: bridge'in baslattigi eklenti surecleri bu is nesnesine baglanir.
// Is nesnesi KILL_ON_JOB_CLOSE ile olusturulur: bridge kapandiginda (normal cikis, cokme,
// guncelleme ile yeniden baslatma) tutamac isletim sistemince kapatilir ve bagli tum
// surecler otomatik sonlandirilir. Boylece eklenti surecleri oksuz kalmaz ve plugin.exe
// kilitli kalmaz.

import (
	"sync"
	"unsafe"

	"golang.org/x/sys/windows"
)

var (
	isNesnesiOnce    sync.Once
	isNesnesiTutamak windows.Handle
	isNesnesiHata    error
)

// yeniIsNesnesi: KILL_ON_JOB_CLOSE bayragiyla bir is nesnesi olusturur.
func yeniIsNesnesi() (windows.Handle, error) {
	h, err := windows.CreateJobObject(nil, nil)
	if err != nil {
		return 0, err
	}
	info := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{}
	info.BasicLimitInformation.LimitFlags = windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
	if _, err := windows.SetInformationJobObject(
		h,
		windows.JobObjectExtendedLimitInformation,
		uintptr(unsafe.Pointer(&info)),
		uint32(unsafe.Sizeof(info)),
	); err != nil {
		_ = windows.CloseHandle(h)
		return 0, err
	}
	return h, nil
}

// isNesnesiHazirla: bridge omru boyunca tek bir is nesnesi kullanilir.
func isNesnesiHazirla() error {
	isNesnesiOnce.Do(func() {
		isNesnesiTutamak, isNesnesiHata = yeniIsNesnesi()
	})
	return isNesnesiHata
}

// surecIsNesnesineAta: verilen surec kimligini (pid) is nesnesine baglar.
func surecIsNesnesineAta(is windows.Handle, pid int) error {
	h, err := windows.OpenProcess(windows.PROCESS_SET_QUOTA|windows.PROCESS_TERMINATE, false, uint32(pid))
	if err != nil {
		return err
	}
	defer windows.CloseHandle(h)
	return windows.AssignProcessToJobObject(is, h)
}

// surecIsNesnesineBagla: bridge'in ana is nesnesine baglar. Hata olursa surec calismaya devam eder
// (eski davranis); yalnizca gunluge yazilir.
func surecIsNesnesineBagla(pid int) {
	if err := isNesnesiHazirla(); err != nil {
		olayLog("is nesnesi olusturulamadi: %v", err)
		return
	}
	if err := surecIsNesnesineAta(isNesnesiTutamak, pid); err != nil {
		olayLog("surec is nesnesine baglanamadi (pid %d): %v", pid, err)
	}
}
