package main

// system_status_test.go — ozellik durum listesinin kurallarini sinar.
//
// Buradaki testler UX sözleşmesini korur: "kapali" ile "eksik ayarli" AYRI
// bildirilir ve eksik ayar icin kullaniciya ne yapacagi soylenir.

import (
	"strings"
	"testing"

	"fiko-ai/config"
)

func featureByKey(cfg config.Config, key string) (found bool, enabled, configured bool, hint string) {
	for _, f := range systemFeatures(cfg) {
		if f.Key == key {
			return true, f.Enabled, f.Configured, f.Hint
		}
	}
	return false, false, false, ""
}

func TestSystemFeaturesCoversAllGroups(t *testing.T) {
	fs := systemFeatures(config.Config{})
	groups := map[string]int{}
	keys := map[string]bool{}
	for _, f := range fs {
		if f.Key == "" || f.Title == "" || f.Group == "" {
			t.Errorf("eksik alan: %+v", f)
		}
		if keys[f.Key] {
			t.Errorf("yinelenen anahtar: %s", f.Key)
		}
		keys[f.Key] = true
		groups[f.Group]++
	}
	for _, g := range []string{"Konuşma", "Ses", "Araçlar", "Veri"} {
		if groups[g] == 0 {
			t.Errorf("grup boş: %s", g)
		}
	}
}

func TestSTTDisabledButConfigured(t *testing.T) {
	cfg := config.Config{}
	cfg.STT = config.STT{Enabled: false, Provider: "whispercpp", URL: "http://127.0.0.1:9000/inference"}
	ok, enabled, configured, hint := featureByKey(cfg, "stt")
	if !ok {
		t.Fatal("stt özelliği yok")
	}
	if enabled {
		t.Error("STT_ENABLED=false iken enabled true olmamalı")
	}
	if !configured {
		t.Error("URL dolu iken configured false olmamalı (motor hazır, sadece kapalı)")
	}
	if !strings.Contains(hint, "STT_ENABLED") {
		t.Errorf("ipucu ne yapılacağını söylemeli, got: %q", hint)
	}
}

func TestSTTEnabledButURLMissing(t *testing.T) {
	cfg := config.Config{}
	cfg.STT = config.STT{Enabled: true, Provider: "whispercpp", URL: ""}
	_, enabled, configured, hint := featureByKey(cfg, "stt")
	if !enabled {
		t.Error("enabled true olmalı")
	}
	if configured {
		t.Error("URL boşken configured false olmalı")
	}
	if !strings.Contains(hint, "STT_URL") {
		t.Errorf("ipucu eksik ayarı göstermeli, got: %q", hint)
	}
}

// API anahtari OPSIYONELDIR: yerel (anahtarsiz) OpenAI-uyumlu motorlar da calisir.
// Canli bulgu: anahtari zorunlu saymak, CALISAN sistemi "eksik" gosteriyordu.
func TestSTTWorksWithoutAPIKey(t *testing.T) {
	cfg := config.Config{}
	cfg.STT = config.STT{Enabled: true, Provider: "openai", URL: "http://127.0.0.1:9000/v1/audio/transcriptions"}
	_, enabled, configured, hint := featureByKey(cfg, "stt")
	if !enabled || !configured {
		t.Errorf("anahtarsiz yerel motor calisir: enabled=%v configured=%v", enabled, configured)
	}
	if hint != "" {
		t.Errorf("calisan ozellige ipucu verilmemeli, got: %q", hint)
	}
}
func TestTTSConfiguredRequiresURL(t *testing.T) {
	cfg := config.Config{}
	cfg.TTS = config.TTS{Enabled: true, Provider: "piper", URL: ""}
	if _, _, configured, _ := featureByKey(cfg, "tts"); configured {
		t.Error("URL boşken configured false olmalı")
	}
	cfg.TTS.URL = "http://127.0.0.1:5000"
	if _, _, configured, _ := featureByKey(cfg, "tts"); !configured {
		t.Error("URL doluyken configured true olmalı")
	}
}

func TestLLMRequiresModel(t *testing.T) {
	cfg := config.Config{}
	cfg.Ollama = config.Ollama{BaseURL: "http://127.0.0.1:11434", Model: ""}
	if _, _, configured, hint := featureByKey(cfg, "llm"); configured {
		t.Error("model boşken configured false olmalı")
	} else if !strings.Contains(hint, "OLLAMA") {
		t.Errorf("ipucu model ayarını göstermeli, got: %q", hint)
	}
	cfg.Ollama.Model = "qwen2.5:7b"
	if _, _, configured, _ := featureByKey(cfg, "llm"); !configured {
		t.Error("model doluyken configured true olmalı")
	}
}

func TestExecNeedsBothEnabledAndList(t *testing.T) {
	cfg := config.Config{}
	cfg.Tools.ExecEnabled = true
	if _, _, configured, _ := featureByKey(cfg, "tools.exec"); configured {
		t.Error("izin listesi boşken configured false olmalı")
	}
	cfg.Tools.ExecAllowed = []string{"C:/Windows/System32/cmd.exe"}
	if _, _, configured, _ := featureByKey(cfg, "tools.exec"); !configured {
		t.Error("izin listesi doluyken configured true olmalı")
	}
}

func TestHTTPAllowPrivateWarns(t *testing.T) {
	cfg := config.Config{}
	cfg.Tools.HTTPAllowPrivate = true
	var detail string
	for _, f := range systemFeatures(cfg) {
		if f.Key == "tools.http" {
			detail = f.Detail
		}
	}
	if !strings.Contains(detail, "SSRF") {
		t.Errorf("özel ağ açıkken uyarı görünmeli, got: %q", detail)
	}
}

func TestWorkingFeatureHasNoHint(t *testing.T) {
	cfg := config.Config{}
	cfg.Tools = config.Tools{BizEnabled: true, WebEnabled: true, HTTPEnabled: true}
	cfg.STT = config.STT{Enabled: true, Provider: "whispercpp", URL: "http://x"}
	cfg.Ollama = config.Ollama{BaseURL: "http://x", Model: "m"}
	_, _, _, hint := featureByKey(cfg, "stt")
	if hint != "" {
		t.Errorf("çalışan özellikte ipucu olmamalı, got: %q", hint)
	}
}

// TestSystemStatusLeaksNoSecrets, /api/system ciktisinda gizli deger OLMADIGINI
// garanti eder.
//
// CANLI BULGU: mongoDetail onceki surumde URI'yi OLDUGU GIBI yaziyordu.
// URI kullanici adi + sifre icerebilir ("mongodb://fiko:sifre@host") ve bu deger
// ekran goruntusu, log ve tarayici gecminde kalir. bizDetail de mutlak dosya
// yolunu (kullanici dizini) ifsa ediyordu. Bu test geri donusu engeller.
func TestSystemStatusLeaksNoSecrets(t *testing.T) {
	cfg := config.Config{}
	cfg.Mongo.URI = "mongodb://fiko:GIZLI-SIFRE@10.0.0.5:27017/fiko"
	cfg.Tools.BizPath = "C:\\Users\\fikokullanici\\gizli\\biz.json"
	cfg.Ollama.BaseURL = "http://localhost:11434"
	cfg.Ollama.EmbedModel = "nomic-embed-text"

	for _, f := range systemFeatures(cfg) {
		for _, s := range []string{"GIZLI-SIFRE", "fikokullanici", "10.0.0.5", "mongodb://", "\\Users\\"} {
			if strings.Contains(f.Detail, s) {
				t.Errorf("%s detayinda gizli deger %q sizdi: %q", f.Key, s, f.Detail)
			}
		}
	}
}

// TestMongoNotAlwaysReady: MongoDB tanimli degilken panel "hazir" DEMEMELI;
// veri bellekte tutulur ve sunucu kapaninca kaybolur.
func TestMongoNotAlwaysReady(t *testing.T) {
	var cfg config.Config
	for _, f := range systemFeatures(cfg) {
		if f.Key != "mongo" {
			continue
		}
		if f.Enabled || f.Configured {
			t.Errorf("URI yokken mongo hazir görünmemeli: %+v", f)
		}
		if f.Hint == "" {
			t.Error("kullanıcıya ne yapması gerektiği söylenmeli")
		}
	}
	// URI tanimliyse hazır.
	cfg.Mongo.URI = "mongodb://localhost:27017"
	for _, f := range systemFeatures(cfg) {
		if f.Key == "mongo" && !f.Enabled {
			t.Error("URI tanımlıyken mongo hazır olmalı")
		}
	}
}

// TestKnowledgeReportsVectorAvailability: vektor arama embedding modeline
// baglidir; model yokken "tam hazır" denmemeli.
func TestKnowledgeReportsVectorAvailability(t *testing.T) {
	var cfg config.Config
	cfg.Ollama.BaseURL = "http://localhost:11434"
	cfg.Ollama.EmbedModel = ""
	for _, f := range systemFeatures(cfg) {
		if f.Key == "knowledge" && strings.Contains(f.Detail, "vektor + anahtar-kelime") {
			t.Errorf("embedding modeli yokken vektor arama hazır görünmemeli: %q", f.Detail)
		}
	}
	cfg.Ollama.EmbedModel = "nomic-embed-text"
	for _, f := range systemFeatures(cfg) {
		if f.Key == "knowledge" && !strings.Contains(f.Detail, "vektor") {
			t.Errorf("embedding modeli varken vektor arama bildirilmeli: %q", f.Detail)
		}
	}
}
