package security

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
)

// SecurityManager управляет всеми аспектами безопасности VPN
type SecurityManager struct {
	killSwitch    *KillSwitch
	dnsProtection *DNSProtection
	configDir     string
	password      string
}

// SecurityConfig хранит настройки безопасности
type SecurityConfig struct {
	KillSwitchEnabled    bool     `json:"kill_switch_enabled"`
	DNSProtectionEnabled bool     `json:"dns_protection_enabled"`
	EncryptionEnabled    bool     `json:"encryption_enabled"`
	VPNDNSServers        []string `json:"vpn_dns_servers"`
	AllowedVPNIPs        []string `json:"allowed_vpn_ips"`
}

// NewSecurityManager создает новый менеджер безопасности
func NewSecurityManager(configDir string, password string) *SecurityManager {
	return &SecurityManager{
		killSwitch:    NewKillSwitch(),
		dnsProtection: NewDNSProtection(),
		configDir:     configDir,
		password:      password,
	}
}

// LoadSecurityConfig загружает конфигурацию безопасности
func (sm *SecurityManager) LoadSecurityConfig() (*SecurityConfig, error) {
	configPath := filepath.Join(sm.configDir, "security.json")
	
	// Если файл не существует, создаем дефолтную конфигурацию с ОТКЛЮЧЕННЫМ Kill Switch
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		defaultConfig := &SecurityConfig{
			KillSwitchEnabled:    false, // ОТКЛЮЧЕНО ПО УМОЛЧАНИЮ!
			DNSProtectionEnabled: true,
			EncryptionEnabled:    true,
			VPNDNSServers:        []string{"1.1.1.1", "8.8.8.8"},
			AllowedVPNIPs:        []string{},
		}
		sm.SaveSecurityConfig(defaultConfig)
		return defaultConfig, nil
	}

	data, err := os.ReadFile(configPath)
	if err != nil {
		return nil, fmt.Errorf("ошибка чтения конфигурации безопасности: %w", err)
	}

	var config SecurityConfig
	if err := json.Unmarshal(data, &config); err != nil {
		return nil, fmt.Errorf("ошибка парсинга конфигурации: %w", err)
	}

	return &config, nil
}

// SaveSecurityConfig сохраняет конфигурацию безопасности
func (sm *SecurityManager) SaveSecurityConfig(config *SecurityConfig) error {
	configPath := filepath.Join(sm.configDir, "security.json")
	
	data, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		return fmt.Errorf("ошибка сериализации конфигурации: %w", err)
	}

	if err := os.WriteFile(configPath, data, 0600); err != nil {
		return fmt.Errorf("ошибка сохранения конфигурации: %w", err)
	}

	return nil
}

// EnableProtection включает все защитные механизмы
func (sm *SecurityManager) EnableProtection(vpnInterface string, vpnServerIP string) error {
	config, err := sm.LoadSecurityConfig()
	if err != nil {
		return err
	}

	// KILL SWITCH ПОЛНОСТЬЮ ОТКЛЮЧЕН - НЕ ИСПОЛЬЗУЕТСЯ!
	// Оставляем только защиту DNS
	
	// Включаем защиту DNS
	if config.DNSProtectionEnabled {
		if err := sm.dnsProtection.Enable(config.VPNDNSServers); err != nil {
			fmt.Printf("⚠ Предупреждение: не удалось включить защиту DNS: %v\n", err)
		} else {
			fmt.Println("✓ Защита DNS включена (предотвращение DNS утечек)")
		}
	}

	return nil
}

// DisableProtection отключает все защитные механизмы
func (sm *SecurityManager) DisableProtection() error {
	var errors []error

	// KILL SWITCH НЕ ИСПОЛЬЗУЕТСЯ - пропускаем

	// Отключаем защиту DNS
	if sm.dnsProtection.IsEnabled() {
		if err := sm.dnsProtection.Disable(); err != nil {
			errors = append(errors, fmt.Errorf("ошибка отключения защиты DNS: %w", err))
		} else {
			fmt.Println("✓ Защита DNS отключена")
		}
	}

	if len(errors) > 0 {
		return fmt.Errorf("ошибки при отключении защиты: %v", errors)
	}

	return nil
}

// EncryptConfigFile шифрует файл конфигурации
func (sm *SecurityManager) EncryptConfigFile(filePath string) error {
	// Читаем файл
	data, err := os.ReadFile(filePath)
	if err != nil {
		return fmt.Errorf("ошибка чтения файла: %w", err)
	}

	// Шифруем
	encrypted, err := Encrypt(data, sm.password)
	if err != nil {
		return fmt.Errorf("ошибка шифрования: %w", err)
	}

	// Сохраняем зашифрованный файл
	encryptedPath := filePath + ".encrypted"
	if err := os.WriteFile(encryptedPath, []byte(encrypted), 0600); err != nil {
		return fmt.Errorf("ошибка сохранения зашифрованного файла: %w", err)
	}

	// Безопасно удаляем оригинальный файл
	if err := SecureDelete(filePath); err != nil {
		return fmt.Errorf("ошибка удаления оригинального файла: %w", err)
	}

	// Переименовываем зашифрованный файл
	if err := os.Rename(encryptedPath, filePath); err != nil {
		return fmt.Errorf("ошибка переименования файла: %w", err)
	}

	return nil
}

// DecryptConfigFile расшифровывает файл конфигурации
func (sm *SecurityManager) DecryptConfigFile(filePath string) ([]byte, error) {
	// Читаем зашифрованный файл
	encryptedData, err := os.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("ошибка чтения файла: %w", err)
	}

	// Расшифровываем
	decrypted, err := Decrypt(string(encryptedData), sm.password)
	if err != nil {
		return nil, fmt.Errorf("ошибка расшифровки: %w", err)
	}

	return decrypted, nil
}

// ProtectConfigDirectory защищает директорию с конфигурациями
func (sm *SecurityManager) ProtectConfigDirectory() error {
	if err := ProtectDirectory(sm.configDir); err != nil {
		return fmt.Errorf("ошибка защиты директории: %w", err)
	}
	
	fmt.Printf("✓ Директория конфигураций защищена: %s\n", sm.configDir)
	return nil
}

// GetSecurityStatus возвращает текущий статус безопасности
func (sm *SecurityManager) GetSecurityStatus() map[string]interface{} {
	config, _ := sm.LoadSecurityConfig()
	
	currentDNS, _ := GetCurrentDNS()
	
	return map[string]interface{}{
		"kill_switch_enabled":     sm.killSwitch.IsEnabled(),
		"dns_protection_enabled":  sm.dnsProtection.IsEnabled(),
		"encryption_enabled":      config.EncryptionEnabled,
		"current_dns_servers":     currentDNS,
		"configured_vpn_dns":      config.VPNDNSServers,
		"config_dir_protected":    true,
	}
}

// CheckForLeaks проверяет наличие утечек
func (sm *SecurityManager) CheckForLeaks() ([]string, error) {
	var leaks []string

	// Проверяем DNS утечки
	currentDNS, err := GetCurrentDNS()
	if err == nil {
		config, _ := sm.LoadSecurityConfig()
		if config.DNSProtectionEnabled {
			// Проверяем, что используются только VPN DNS
			for _, dns := range currentDNS {
				isVPNDNS := false
				for _, vpnDNS := range config.VPNDNSServers {
					if dns == vpnDNS {
						isVPNDNS = true
						break
					}
				}
				if !isVPNDNS {
					leaks = append(leaks, fmt.Sprintf("DNS утечка: используется %s вместо VPN DNS", dns))
				}
			}
		}
	}

	// Проверяем Kill Switch
	if !sm.killSwitch.IsEnabled() {
		config, _ := sm.LoadSecurityConfig()
		if config.KillSwitchEnabled {
			leaks = append(leaks, "Kill Switch не активен, возможна утечка трафика при разрыве VPN")
		}
	}

	return leaks, nil
}
