#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Модуль для взаимодействия с API Synology NAS
"""

import requests
from requests.adapters import HTTPAdapter
import json
import logging
import time
import urllib3
from urllib3.util import Retry
from typing import Dict, Any, Optional, List
import socket
import struct
from time import sleep

from src.config.config import (
    SYNOLOGY_HOST, 
    SYNOLOGY_PORT,
    SYNOLOGY_USERNAME,
    SYNOLOGY_PASSWORD,
    SYNOLOGY_SECURE,
    SYNOLOGY_TIMEOUT,
    SYNOLOGY_MAC,
    WOL_PORT,
    SYNOLOGY_API_VERSION,
    SYNOLOGY_POWER_API,
    SYNOLOGY_INFO_API
)
from src.api.api_discovery import discover_available_apis, find_compatible_api

# Отключение предупреждений о небезопасных SSL-соединениях
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

logger = logging.getLogger(__name__)

class SynologyAPI:
    """Класс для взаимодействия с API Synology NAS"""
    
    def __init__(self):
        """Инициализация класса SynologyAPI"""
        logger.info("Creating API with auto-retry and connection pool")
        logger.debug(f"Connection details: Host={SYNOLOGY_HOST}, Port={SYNOLOGY_PORT}, Secure={SYNOLOGY_SECURE}")
        
        self.protocol = "https" if SYNOLOGY_SECURE else "http"
        self.base_url = f"{self.protocol}://{SYNOLOGY_HOST}:{SYNOLOGY_PORT}/webapi"
        self.sid = None
        self.session = requests.Session()
        
        # Настройка SSL
        if self.protocol == "https":
            logger.debug("SSL enabled, disabling certificate verification for internal network")
            self.session.verify = False  # Отключаем проверку SSL для внутренней сети
        
        # Добавляем пользовательские заголовки для улучшения совместимости с API
        custom_headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
            'X-Requested-With': 'XMLHttpRequest',
            'Connection': 'keep-alive',
            'Referer': f'{self.protocol}://{SYNOLOGY_HOST}:{SYNOLOGY_PORT}/'
        }
        self.session.headers.update(custom_headers)
        logger.debug("Added browser-like headers for API compatibility")
        
        # Добавляем повторные попытки для HTTP-запросов
        retry_strategy = Retry(
            total=5,  # Увеличиваем количество попыток
            status_forcelist=[429, 500, 502, 503, 504, 404],
            allowed_methods=["GET", "POST"],
            backoff_factor=1.5,  # Увеличиваем задержку между попытками
            respect_retry_after_header=True
        )
        adapter = HTTPAdapter(
            max_retries=retry_strategy, 
            pool_connections=3, 
            pool_maxsize=10
        )
        self.session.mount("http://", adapter)
        self.session.mount("https://", adapter)
        
        # Таймауты будут указаны в запросах
        self.default_timeout = (SYNOLOGY_TIMEOUT, SYNOLOGY_TIMEOUT*2)
        logger.debug(f"Setting default request timeout: {self.default_timeout}")
        
        # Кэш для хранения результатов запросов
        self._cache = {}
        self._cache_ttl = {}
        self._last_online_check = 0
        self._last_online_status = False
        self._online_check_interval = 30  # Интервал для кэширования проверок онлайн-статуса
        
        # Время последней успешной аутентификации и срок действия сессии
        self._last_auth_time = 0
        self._auth_expiry = 3600  # По умолчанию 1 час
        
        # Информация о доступных API
        self._available_apis = {}
        self._api_info_ttl = 0
        
        # Инициализируем API version resolver для автоматического определения совместимых API
        self.api_resolver = None  # Будет создан при необходимости
        
    def login(self) -> bool:
        """Авторизация в API Synology NAS"""
        # Сбрасываем SID для новой сессии
        self.sid = None
        
        logger.info("Attempting to authenticate with Synology NAS...")
        logger.debug(f"Base URL: {self.base_url}")
        
        # Проверяем доступность NAS перед запросом с помощью прямой TCP-проверки
        # Избегаем вызова is_online(), чтобы не создавать рекурсию
        online_status = self._check_tcp_connection()
        if not online_status:
            logger.error("Cannot login: Synology NAS is not reachable")
            return False
            
        # Пробуем различные версии API для аутентификации
        # Начинаем с версии 3, которая показала лучшую совместимость в тестах
        auth_versions_to_try = [3, 2, 1, 6]  # Пробуем сначала более стабильные версии
        
        for auth_version in auth_versions_to_try:
            try:
                # Определяем путь к API аутентификации
                auth_path = "entry.cgi"  # Используем entry.cgi вместо auth.cgi по умолчанию
                
                # Проверка информации API для определения доступных версий API
                api_info_url = f"{self.base_url}/entry.cgi"
                api_info_params = {
                    "api": "SYNO.API.Info",
                    "version": "1",
                    "method": "query",
                    "query": "SYNO.API.Auth"
                }
                
                logger.debug(f"Querying API info for auth version {auth_version}")
                try:
                    api_info_response = self.session.get(
                        api_info_url,
                        params=api_info_params,
                        timeout=self.default_timeout,
                        verify=False
                    )
                    
                    if api_info_response.status_code == 200:
                        api_info_data = api_info_response.json()
                        if api_info_data.get("success"):
                            auth_info = api_info_data.get("data", {}).get("SYNO.API.Auth", {})
                            max_version = auth_info.get("maxVersion", 6)
                            min_version = auth_info.get("minVersion", 1)
                            auth_path = auth_info.get("path", "entry.cgi")
                            logger.debug(f"Auth API versions: min={min_version}, max={max_version}, path={auth_path}")
                            
                            # Проверяем поддержку текущей версии
                            if auth_version < min_version or auth_version > max_version:
                                logger.warning(f"Auth API version {auth_version} not supported (min={min_version}, max={max_version}), trying next version")
                                continue
                        else:
                            logger.warning("Failed to query API info, using default auth path")
                    else:
                        logger.warning(f"API info request failed with status {api_info_response.status_code}, using default auth path")
                except Exception as e:
                    logger.warning(f"Error querying API info: {str(e)}, using default auth path")
                    
                # Основной запрос авторизации
                url = f"{self.base_url}/{auth_path}"
                params = {
                    "api": "SYNO.API.Auth",
                    "version": str(auth_version),
                    "method": "login",
                    "account": SYNOLOGY_USERNAME,
                    "passwd": SYNOLOGY_PASSWORD,
                    "session": "SynologyPowerControlBot",
                    "format": "cookie"
                }
                
                # Для версии 6+ используем немного другой формат
                if auth_version >= 6:
                    params["enable_syno_token"] = "yes"
                
                logger.debug(f"Sending auth request to {url} with API version {auth_version}")
                start_time = time.time()
                response = self.session.get(
                    url, 
                    params=params, 
                    timeout=self.default_timeout, 
                    verify=False
                )
                elapsed_time = time.time() - start_time
                logger.debug(f"Auth request completed in {elapsed_time:.2f}s with status code {response.status_code}")
                
                # Проверка статуса HTTP
                if response.status_code != 200:
                    logger.error(f"HTTP error: {response.status_code}")
                    logger.debug(f"Response content: {response.text[:200]}")
                    continue  # Пробуем следующую версию
                    
                try:
                    data = response.json()
                except json.JSONDecodeError:
                    logger.error("Failed to decode JSON response")
                    logger.debug(f"Response content: {response.text[:200]}")
                    continue  # Пробуем следующую версию
                
                if data.get("success"):
                    self.sid = data.get("data", {}).get("sid")
                    self._last_auth_time = time.time()
                    logger.info(f"Successfully logged in to Synology NAS using API version {auth_version}")
                    logger.debug(f"Session ID obtained: {self.sid[:5] if self.sid else 'None'}...")
                    
                    # Получаем и сохраняем токен SYNO, если он есть
                    syno_token = data.get("data", {}).get("synotoken")
                    if syno_token:
                        self.session.headers.update({'X-SYNO-TOKEN': syno_token})
                        logger.debug("Added X-SYNO-TOKEN header for improved API compatibility")
                    
                    # Также добавляем SID в cookies для улучшения совместимости
                    self.session.cookies.update({
                        'id': self.sid,
                        'sid': self.sid
                    })
                    logger.debug("Added SID to session cookies for improved compatibility")
                    
                    # Проверка валидности полученной сессии с помощью простого запроса
                    # Будем использовать SYNO.API.Info без проверки сложных методов
                    
                    # Даем системе немного времени для инициализации сессии
                    time.sleep(0.5)
                        
                    return True
                else:
                    error_code = data.get("error", {}).get("code", -1)
                    logger.error(f"Failed to log in with version {auth_version}: Error code {error_code}")
                    
                    # Если ошибка связана с версией API, пробуем следующую версию
                    if error_code in [104, 105]:
                        logger.warning(f"Auth version {auth_version} not supported, trying next version")
                        continue
                    
                    # Дополнительная диагностика
                    if error_code == 400:
                        logger.error("Authentication error: Invalid credentials")
                    elif error_code == 401:
                        logger.error("Authentication error: Account disabled")
                    elif error_code == 402:
                        logger.error("Authentication error: Permission denied")
                    elif error_code == 403:
                        logger.error("Authentication error: 2-factor authentication required")
                    elif error_code == 404:
                        logger.error("Authentication error: Failed to authenticate with 2-factor authentication")
                    
                    # Если ошибка связана с неверными учетными данными, нет смысла пробовать другие версии API
                    if error_code in [400, 401, 402, 403, 404]:
                        return False
                    
            except requests.exceptions.Timeout:
                logger.error(f"Connection timeout during auth with version {auth_version}")
                continue  # Пробуем следующую версию
            except requests.exceptions.ConnectionError as e:
                logger.error(f"Connection error during auth with version {auth_version}: {str(e)}")
                continue  # Пробуем следующую версию
            except requests.RequestException as e:
                logger.error(f"Request error during auth with version {auth_version}: {str(e)}")
                continue  # Пробуем следующую версию
            except Exception as e:
                logger.error(f"Unexpected error during login with version {auth_version}: {str(e)}", exc_info=True)
                continue  # Пробуем следующую версию
                
        # Если все версии не сработали
        logger.error("Failed to authenticate with any API version")
        return False
        
    def _validate_session(self) -> bool:
        """Проверяет валидность сессии после авторизации"""
        if not self.sid:
            return False
            
        # Попробуем сделать простой запрос для проверки сессии
        test_apis = [
            {"api": "SYNO.Core.System", "method": "info", "version": 1},
            {"api": "SYNO.DSM.Info", "method": "getinfo", "version": 1}
        ]
        
        for test_api in test_apis:
            try:
                url = f"{self.base_url}/entry.cgi"
                params = {
                    "api": test_api["api"],
                    "version": str(test_api["version"]),
                    "method": test_api["method"],
                    "_sid": self.sid
                }
                
                response = self.session.get(url, params=params, timeout=self.default_timeout, verify=False)
                
                if response.status_code == 200:
                    data = response.json()
                    if data.get("success"):
                        logger.debug(f"Session validation successful using {test_api['api']}")
                        return True
                    else:
                        error_code = data.get("error", {}).get("code", -1)
                        if error_code != 119:  # Не сессия истекла
                            logger.debug(f"Session validation with {test_api['api']} returned error code {error_code}")
                            return True  # Считаем сессию валидной, если ошибка не связана с истечением сессии
            except Exception as e:
                logger.warning(f"Error during session validation with {test_api['api']}: {str(e)}")
                
        logger.warning("Session validation failed with all test APIs")
        return False
    
    def logout(self) -> bool:
        """Выход из API Synology NAS"""
        if not self.sid:
            return True
            
        try:
            url = f"{self.base_url}/auth.cgi"
            params = {
                "api": "SYNO.API.Auth",
                "version": "1",
                "method": "logout",
                "session": "SynologyPowerControlBot",
                "_sid": self.sid
            }
            
            response = self.session.get(url, params=params, timeout=SYNOLOGY_TIMEOUT, verify=False)
            data = response.json()
            
            if data.get("success"):
                self.sid = None
                logger.info("Successfully logged out from Synology NAS")
                return True
            else:
                error_code = data.get("error", {}).get("code", -1)
                logger.error(f"Failed to log out from Synology NAS: Error code {error_code}")
                return False
                
        except requests.RequestException as e:
            logger.error(f"Connection error: {str(e)}")
            return False
    
    def _make_api_request(self, api_name: str, method: str, version: int = 1, 
                         params: Optional[Dict[str, Any]] = None, retry_auth: bool = True, retry_count: int = 0) -> Optional[Dict[str, Any]]:
        """Обобщенный метод для выполнения API запросов с обработкой ошибок"""
        # Ограничение на количество повторных попыток
        if retry_count >= 3:
            logger.error(f"Too many retries for {api_name}.{method}, giving up")
            return None
            
        # Проверка наличия авторизации
        if not self.sid and not self.login():
            logger.error(f"Not authenticated for API request: {api_name}.{method}")
            return None
            
        # Проверка информации API для определения пути и поддерживаемой версии
        api_info_url = f"{self.base_url}/entry.cgi"
        api_info_params = {
            "api": "SYNO.API.Info",
            "version": "1",
            "method": "query",
            "query": api_name
        }
        
        api_path = "entry.cgi"
        try:
            logger.debug(f"Querying API info for {api_name}")
            api_info_response = self.session.get(
                api_info_url,
                params=api_info_params,
                timeout=self.default_timeout,
                verify=False
            )
            
            if api_info_response.status_code == 200:
                api_info_data = api_info_response.json()
                if api_info_data.get("success"):
                    api_info = api_info_data.get("data", {}).get(api_name, {})
                    if api_info:
                        max_version = api_info.get("maxVersion", version)
                        min_version = api_info.get("minVersion", version)
                        api_path = api_info.get("path", "entry.cgi")
                        
                        # Проверка, поддерживается ли запрошенная версия
                        if version < min_version:
                            logger.warning(f"API version {version} for {api_name} is below minimum {min_version}, using {min_version}")
                            version = min_version
                        elif version > max_version:
                            logger.warning(f"API version {version} for {api_name} exceeds maximum {max_version}, using {max_version}")
                            version = max_version
                            
                        logger.debug(f"Using API path: {api_path}, version: {version}")
                    else:
                        logger.warning(f"API {api_name} not found in API info, using defaults")
        except Exception as e:
            logger.warning(f"Error querying API info for {api_name}: {str(e)}, using defaults")
            
        # Подготовка базовых параметров запроса
        base_params = {
            "api": api_name,
            "version": str(version),
            "method": method,
            "_sid": self.sid  # Используем _sid вместо sid для лучшей совместимости
        }
        
        # Добавление дополнительных параметров, если они заданы
        if params:
            base_params.update(params)
        
        url = f"{self.base_url}/{api_path}"
        logger.debug(f"API request: {api_name}.{method} v{version} to {url}")
        logger.debug(f"Full request params: {base_params}")
        
        try:
            start_time = time.time()
            response = self.session.get(
                url, 
                params=base_params, 
                timeout=self.default_timeout, 
                verify=False
            )
            elapsed_time = time.time() - start_time
            logger.debug(f"API request completed in {elapsed_time:.2f}s with status {response.status_code}")
            
            # Проверка статуса HTTP
            if response.status_code != 200:
                logger.error(f"HTTP error: {response.status_code} for {api_name}.{method}")
                
                # Повторная попытка при ошибках соединения
                if response.status_code in [500, 502, 503, 504]:
                    logger.info(f"Server error, retrying request for {api_name}.{method}")
                    sleep(2)
                    return self._make_api_request(api_name, method, version, params, retry_auth, retry_count + 1)
                    
                return None
                
            try:
                data = response.json()
            except json.JSONDecodeError:
                logger.error(f"Failed to decode JSON response for {api_name}.{method}")
                logger.debug(f"Response content: {response.text[:200]}")
                
                # Повторная попытка при ошибках декодирования
                logger.info(f"JSON decode error, retrying request for {api_name}.{method}")
                sleep(2)
                return self._make_api_request(api_name, method, version, params, retry_auth, retry_count + 1)
                
            if data.get("success"):
                logger.info(f"API request successful for {api_name}.{method}")
                return data.get("data", {})
            else:
                error_code = data.get("error", {}).get("code", -1)
                error_desc = self._get_error_description(error_code)
                logger.error(f"API error for {api_name}.{method}: {error_code} - {error_desc}")
                
                # Ошибки доступа или прав часто встречаются, но они не критичные
                # Например, ошибка 102 означает, что нет прав, но NAS доступен
                if error_code in [102, 103, 104, 105]:
                    logger.warning(f"Permission-related error for {api_name}.{method}: {error_code}")
                    # Возвращаем пустой словарь вместо None,
                    # чтобы вызывающий код мог понять, что запрос выполнен
                    return {}
                
                # Если ошибка связана с авторизацией и нам разрешено повторить попытку
                if error_code in [106, 107, 119] and retry_auth:
                    logger.info(f"Session error (code {error_code}), creating fresh session...")
                    self.sid = None  # Сбрасываем SID
                    
                    # Для ошибки 119 (Session timeout) дадим системе немного времени
                    if error_code == 119:
                        logger.info("Session timeout detected, waiting before retry...")
                        sleep(3)
                        
                    if self.login():
                        logger.info("Re-authenticated with fresh session, retrying API request...")
                        # Рекурсивный вызов, но со счетчиком повторов
                        return self._make_api_request(api_name, method, version, params, False, retry_count + 1)
                
                # Для некоторых ошибок можно автоматически повторить запрос
                if error_code in [408, 429, 500, 502, 503, 504]:
                    logger.info(f"Temporary error {error_code}, retrying request for {api_name}.{method}")
                    sleep(2)
                    return self._make_api_request(api_name, method, version, params, retry_auth, retry_count + 1)
                    
                return None
                
        except requests.exceptions.Timeout:
            logger.error(f"Request timeout for {api_name}.{method}")
            
            # Повторная попытка при таймауте
            if retry_count < 2:
                logger.info(f"Timeout, retrying request for {api_name}.{method}")
                sleep(2)
                return self._make_api_request(api_name, method, version, params, retry_auth, retry_count + 1)
                
            return None
        except requests.exceptions.ConnectionError as e:
            logger.error(f"Connection error for {api_name}.{method}: {str(e)}")
            
            # Повторная попытка при ошибке соединения
            if retry_count < 2:
                logger.info(f"Connection error, retrying request for {api_name}.{method}")
                sleep(2)
                return self._make_api_request(api_name, method, version, params, retry_auth, retry_count + 1)
                
            return None
        except Exception as e:
            logger.error(f"Unexpected error during {api_name}.{method}: {str(e)}")
            return None
    
    def get_system_status(self) -> Dict[str, Any]:
        """Получение статуса системы"""
        # Проверяем доступность системы
        if not self.is_online():
            logger.info("Device is offline, skipping API request")
            return {"status": "offline"}
            
        # Проверяем, есть ли кэшированный результат
        cache_key = "system_status"
        current_time = time.time()
        if cache_key in self._cache and current_time - self._cache_ttl.get(cache_key, 0) < 60:
            logger.debug("Using cached system status")
            return self._cache[cache_key]
        
        # Используем рекомендованный API для получения информации о системе
        logger.info(f"Getting system info using {SYNOLOGY_INFO_API} v{SYNOLOGY_API_VERSION}")
        
        # Для SYNO.DSM.Info метод getinfo, для других обычно используется get или info
        if SYNOLOGY_INFO_API == "SYNO.DSM.Info":
            method = "getinfo"
        else:
            method = "get"
            
        result = self._make_api_request(SYNOLOGY_INFO_API, method, version=SYNOLOGY_API_VERSION)
        
        if result:
            logger.info(f"Successfully retrieved system info using {SYNOLOGY_INFO_API}")
            
            # Формируем расширенный ответ с дополнительной информацией
            system_info = {
                "status": "online",
                "hostname": result.get("hostname", "unknown"),
                "model": result.get("model", "unknown"),
                "version": result.get("version", "unknown"),
                "uptime": result.get("uptime", 0),
                "time": current_time,
                "is_online": True,
                "api_used": SYNOLOGY_INFO_API
            }
            
            # Сохраняем в кэше
            self._cache[cache_key] = system_info
            self._cache_ttl[cache_key] = current_time
            
            return system_info
                
        # Если основной API не сработал, пробуем резервные варианты
        logger.warning(f"Failed to retrieve system info with {SYNOLOGY_INFO_API}, trying fallback APIs")
        
        # Пробуем резервные API
        apis_to_try = [
            {"name": "SYNO.DSM.Info", "method": "getinfo", "version": 2},
            {"name": "SYNO.Core.System", "method": "info", "version": 1},
            {"name": "SYNO.Core.System.Status", "method": "get", "version": 1},
            {"name": "SYNO.Core.System.Info", "method": "get", "version": 1},
        ]
        
        for api in apis_to_try:
            if api["name"] == SYNOLOGY_INFO_API:
                continue  # Пропускаем уже проверенный API
                
            logger.info(f"Trying to get system info using {api['name']}.{api['method']} v{api['version']}")
            result = self._make_api_request(api["name"], api["method"], version=api["version"])
            
            if result:
                logger.info(f"Successfully retrieved system info using {api['name']}")
                
                # Формируем расширенный ответ с дополнительной информацией
                system_info = {
                    "status": "online",
                    "hostname": result.get("hostname", "unknown"),
                    "model": result.get("model", "unknown"),
                    "version": result.get("version", "unknown"),
                    "uptime": result.get("uptime", 0),
                    "time": current_time,
                    "is_online": True,
                    "api_used": api["name"]
                }
                
                # Сохраняем в кэше
                self._cache[cache_key] = system_info
                self._cache_ttl[cache_key] = current_time
                
                return system_info
        
        # Если все запросы не удались, но система онлайн, возвращаем базовую информацию
        logger.warning("Failed to retrieve system info with all API methods")
        return {
            "status": "error", 
            "error": "Failed to fetch system information",
            "is_online": True,
            "time": current_time
        }
    
    def shutdown_system(self) -> bool:
        """Выключение системы"""
        # Проверяем, включено ли устройство перед попыткой его выключить
        if not self.is_online(force_check=True):
            logger.info("Synology NAS is already offline, no need to shut down")
            return True
            
        logger.info("Attempting to shutdown Synology NAS...")
        
        # Попробуем сначала использовать предпочтительный API для управления питанием
        logger.info(f"Trying shutdown with {SYNOLOGY_POWER_API} v{SYNOLOGY_API_VERSION}")
        
        # Для SYNO.Core.Hardware.PowerRecovery используется метод setPowerOnState
        # Для других API обычно используется метод shutdown или reboot
        if SYNOLOGY_POWER_API == "SYNO.Core.Hardware.PowerRecovery":
            # Для этого API нужны специальные параметры
            params = {"state": "powerbtn"}  # powerbtn имитирует нажатие кнопки питания
            result = self._make_api_request(SYNOLOGY_POWER_API, "setPowerOnState", version=SYNOLOGY_API_VERSION, params=params)
        else:
            # Пробуем стандартный метод
            result = self._make_api_request(SYNOLOGY_POWER_API, "shutdown", version=SYNOLOGY_API_VERSION)
        
        if result is not None:
            logger.info(f"Successfully initiated system shutdown using {SYNOLOGY_POWER_API}")
            
            # Даем системе время начать процесс выключения
            logger.info("Waiting for shutdown to initialize...")
            sleep(5)
            
            # Проверяем статус
            if not self.is_online(force_check=True):
                logger.info("System is now offline. Shutdown confirmed successful.")
                return True
            else:
                logger.info("System still appears to be online, but shutdown may be in progress.")
                return True
        else:
            logger.warning(f"Failed to shutdown using {SYNOLOGY_POWER_API}, trying alternative methods")
            
            # Если не сработал основной метод, пробуем резервные варианты
            # Проверка всех доступных методов API для выключения
            apis_to_try = [
                {"name": "SYNO.Core.System", "method": "shutdown", "version": 3},
                {"name": "SYNO.Core.System.Power", "method": "shutdown", "version": 1},
                {"name": "SYNO.DSM.Power", "method": "shutdown", "version": 1},
                {"name": "SYNO.System.Power", "method": "shutdown", "version": 1},
                {"name": "SYNO.DSM.System", "method": "shutdown", "version": 1}
            ]
            
            # Проверяем доступные API
            try:
                api_info_url = f"{self.base_url}/entry.cgi"
                api_info_params = {
                    "api": "SYNO.API.Info",
                    "version": "1",
                    "method": "query",
                    "query": "SYNO.Core.System.Power,SYNO.DSM.Power,SYNO.Core.System,SYNO.System.Power,SYNO.DSM.System"
                }
                
                logger.debug("Checking available shutdown APIs")
                api_info_response = self.session.get(
                    api_info_url,
                    params=api_info_params,
                    timeout=self.default_timeout,
                    verify=False
                )
                
                if api_info_response.status_code == 200:
                    api_info_data = api_info_response.json()
                    if api_info_data.get("success"):
                        available_apis = api_info_data.get("data", {})
                        logger.debug(f"Available APIs: {list(available_apis.keys())}")
                        
                        # Фильтруем только доступные API
                        filtered_apis = []
                        for api in apis_to_try:
                            if api["name"] in available_apis:
                                api_info = available_apis[api["name"]]
                                # Проверка версии API
                                if api_info.get("minVersion", 1) <= api["version"] <= api_info.get("maxVersion", 1):
                                    filtered_apis.append(api)
                                    logger.debug(f"Adding {api['name']} to available shutdown APIs")
                                else:
                                    logger.debug(f"API {api['name']} version {api['version']} not supported. Supported: {api_info.get('minVersion')}-{api_info.get('maxVersion')}")
                        
                        if filtered_apis:
                            apis_to_try = filtered_apis
                        else:
                            logger.warning("No compatible APIs found, trying all methods as fallback")
                    else:
                        logger.warning("Failed to query API info, using default methods")
                else:
                    logger.warning(f"API info request failed with status {api_info_response.status_code}, using default methods")
            except Exception as e:
                logger.warning(f"Error querying API info: {str(e)}, using default methods")
            
            # Пробуем все доступные методы по порядку
            for api in apis_to_try:
                logger.info(f"Trying shutdown with {api['name']}.{api['method']} v{api['version']}")
                result = self._make_api_request(api["name"], api["method"], version=api["version"])
                
                if result is not None:
                    logger.info(f"Successfully initiated system shutdown using {api['name']}")
                    
                    # Даем системе время начать процесс выключения
                    logger.info("Waiting for shutdown to initialize...")
                    sleep(5)
                    
                    # Проверяем статус
                    if not self.is_online(force_check=True):
                        logger.info("System is now offline. Shutdown confirmed successful.")
                        return True
                    else:
                        logger.info("System still appears to be online, but shutdown may be in progress.")
                        return True
                else:
                    logger.warning(f"Failed to shutdown using {api['name']}.{api['method']} v{api['version']}")
            
            # Если ни один метод не сработал, но система стала недоступна
            if not self.is_online(force_check=True):
                logger.info("System appears to be shutting down despite API errors")
                return True
                
            logger.error("Failed to shutdown system after trying multiple APIs")
            return False
    
    def reboot_system(self) -> bool:
        """Перезагрузка системы"""
        # Проверяем, включена ли система
        if not self.is_online(force_check=True):
            logger.error("Cannot reboot: System is offline")
            return False
        
        logger.info("Attempting to reboot Synology NAS...")
        
        # Список API и методов для попытки перезагрузки
        apis_to_try = [
            {"api": "SYNO.Core.System", "method": "reboot", "version": 1},
            {"api": "SYNO.DSM.System", "method": "reboot", "version": 1},
            {"api": "SYNO.Core.System.Power", "method": "restart", "version": 1},
            {"api": "SYNO.DSM.Power", "method": "reboot", "version": 1},
            {"api": "SYNO.Core.System", "method": "reboot", "version": 3},
            {"api": "SYNO.System.Power", "method": "reboot", "version": 1},
            {"api": "SYNO.Core.Hardware.NeedReboot", "method": "reboot", "version": 1}
        ]
        
        # Добавляем настроенный в конфигурации API, если он отличается от уже добавленных
        already_added = [item["api"] for item in apis_to_try]
        if SYNOLOGY_POWER_API not in already_added:
            for method in ["restart", "reboot"]:
                apis_to_try.append({
                    "api": SYNOLOGY_POWER_API, 
                    "method": method, 
                    "version": SYNOLOGY_API_VERSION
                })
        
        # Перебираем все возможные API и методы
        for api_info in apis_to_try:
            try:
                logger.info(f"Trying reboot with {api_info['api']} API using method {api_info['method']}")
                result = self._make_api_request(api_info['api'], api_info['method'], version=api_info['version'])
                if result is not None:
                    logger.info(f"Successfully initiated system reboot using {api_info['api']} API")
                    
                    # Даем системе время начать процесс перезагрузки
                    logger.info("Waiting for reboot to initialize...")
                    sleep(5)
                    
                    # Ждем, пока система станет недоступна (признак перезагрузки)
                    reboot_started = False
                    for i in range(12):  # Проверяем в течение 60 секунд (12 * 5сек)
                        if not self.is_online(force_check=True):
                            logger.info(f"System went offline after {i*5} seconds, reboot in progress")
                            reboot_started = True
                            break
                        logger.debug(f"System still online, waiting... ({i+1}/12)")
                        sleep(5)
                    
                    if reboot_started:
                        # Успешный вызов API и система ушла оффлайн - это признак успешной перезагрузки
                        return True
                    else:
                        # Успешный вызов API, но система не ушла оффлайн
                        logger.warning("System did not go offline after reboot command, but command was accepted")
                        # Даже если система не ушла оффлайн, команда могла быть принята
                        return True
            except Exception as e:
                logger.error(f"Error during reboot with {api_info['api']}: {str(e)}")
        
        # Если все попытки не удались, возвращаем False
        logger.error("All reboot attempts failed")
        return False
            for api in apis_to_try:
                logger.info(f"Trying reboot with {api['name']}.{api['method']} v{api['version']}")
                result = self._make_api_request(api["name"], api["method"], version=api["version"])
                
                if result is not None:
                    logger.info(f"Successfully initiated system reboot using {api['name']}")
                    
                    # Даем системе время начать процесс перезагрузки
                    logger.info("Waiting for reboot to initialize...")
                    sleep(5)
                    
                    # Ждем, пока система станет недоступна (признак перезагрузки)
                    reboot_started = False
                    for i in range(12):  # Проверяем в течение 60 секунд (12 * 5сек)
                        if not self.is_online(force_check=True):
                            logger.info(f"System went offline after {i*5} seconds, reboot in progress")
                            reboot_started = True
                            break
                        logger.debug(f"System still online, waiting... ({i+1}/12)")
                        sleep(5)
                        
                    if reboot_started:
                        # Ждем, пока система снова станет доступна
                        logger.info("Waiting for system to come back online...")
                        return self.wait_for_boot(max_attempts=30, delay=10)
                    else:
                        logger.warning("System did not go offline after reboot command, but command was accepted")
                        # Даже если система не ушла оффлайн, команда могла быть принята
                        return True
                else:
                    logger.warning(f"Failed to reboot using {api['name']}.{api['method']} v{api['version']}")
            
            logger.error("Failed to reboot system after trying multiple APIs")
            return False
    
    def _get_error_description(self, error_code: int) -> str:
        """Получение описания ошибки по коду"""
        error_descriptions = {
            100: "Unknown error",
            101: "Invalid parameter",
            102: "API does not exist",
            103: "Method does not exist",
            104: "Version does not support",
            105: "Permission denied",
            106: "Session timeout",
            107: "Session interrupted by duplicate login",
            400: "Invalid credentials",
            401: "Account disabled",
            402: "Permission denied",
            403: "2FA required",
            404: "Failed to authenticate with 2FA"
        }
        return error_descriptions.get(error_code, "Unknown error code")
        
    def _check_tcp_connection(self) -> bool:
        """Проверка базового TCP-соединения с Synology NAS"""
        try:
            socket_obj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            socket_obj.settimeout(SYNOLOGY_TIMEOUT)
            result = socket_obj.connect_ex((SYNOLOGY_HOST, SYNOLOGY_PORT))
            socket_obj.close()
            
            return result == 0
        except socket.error as e:
            logger.error(f"Socket error during connection check: {str(e)}")
            return False
        except Exception as e:
            logger.error(f"Unexpected error during connection check: {str(e)}")
            return False
            
    def is_online(self, force_check=False) -> bool:
        """Проверка онлайн-статуса Synology NAS"""
        # Используем кэшированное значение, если доступно и не устарело
        current_time = time.time()
        if not force_check and (current_time - self._last_online_check) < self._online_check_interval:
            logger.debug(f"Using cached online status: {self._last_online_status}")
            return self._last_online_status
            
        logger.info("Checking if NAS is online...")
        
        # Проверяем TCP-соединение
        online_status = self._check_tcp_connection()
        logger.info(f"Detected Synology NAS online status: {online_status}")
        
        # Если TCP-соединение успешно и у нас есть действующий SID,
        # попробуем более детальную проверку через API
        if online_status and self.sid:
            logger.info("Trying to fetch more detailed online status through API...")
            
            # Пробуем разные API для проверки онлайн-статуса
            api_checks = [
                {"api": "SYNO.DSM.Info", "version": "2", "method": "getinfo"},
                {"api": "SYNO.Core.System", "version": "1", "method": "info"},
                {"api": "SYNO.Core.System.Status", "version": "1", "method": "get"}
            ]
            
            api_success = False
            for api_check in api_checks:
                try:
                    url = f"{self.base_url}/entry.cgi"
                    params = {
                        "api": api_check["api"],
                        "version": api_check["version"],
                        "method": api_check["method"],
                        "sid": self.sid
                    }
                    
                    logger.debug(f"Trying online status check with {api_check['api']}")
                    response = self.session.get(
                        url, 
                        params=params, 
                        timeout=self.default_timeout, 
                        verify=False
                    )
                    
                    if response.status_code == 200:
                        data = response.json()
                        if data.get("success"):
                            logger.info(f"API request successful for {api_check['api']}")
                            logger.info("Synology NAS is online with API access")
                            api_success = True
                            break
                        else:
                            error_code = data.get("error", {}).get("code", -1)
                            logger.warning(f"API response indicates an error: {error_code}, but NAS is reachable")
                    else:
                        logger.warning(f"API returned status code {response.status_code}")
                except Exception as e:
                    logger.warning(f"API check failed for {api_check['api']}, but TCP connection succeeded: {str(e)}")
            
            if not api_success:
                logger.warning("All API checks failed, but TCP connection is successful")
        
        # Обновляем кэшированное значение
        self._last_online_check = current_time
        self._last_online_status = online_status
        
        return online_status
    
    def wake_on_lan(self) -> bool:
        """Отправка Wake-on-LAN пакета для включения Synology NAS"""
        if not SYNOLOGY_MAC:
            logger.error("MAC address not configured")
            return False
            
        try:
            # Преобразование MAC-адреса в байты
            mac_address = SYNOLOGY_MAC.replace(':', '').replace('-', '')
            if len(mac_address) != 12:
                logger.error(f"Invalid MAC address format: {SYNOLOGY_MAC}")
                return False
                
            try:
                mac_bytes = bytes.fromhex(mac_address)
            except ValueError as e:
                logger.error(f"Failed to parse MAC address: {str(e)}")
                logger.error(f"MAC address must contain only hex characters: {SYNOLOGY_MAC}")
                return False
            
            # Создание Magic Packet
            magic_packet = b'\xff' * 6 + mac_bytes * 16
            
            # Отправка пакета на конкретный адрес
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
                sock.sendto(magic_packet, (SYNOLOGY_HOST, WOL_PORT))
                sock.close()
                logger.info(f"Wake-on-LAN packet sent to {SYNOLOGY_MAC} at {SYNOLOGY_HOST}:{WOL_PORT}")
            except Exception as e:
                logger.error(f"Error sending directed WoL packet: {str(e)}")
                return False
                
            # Для надежности отправляем также широковещательный пакет
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
                
                # Используем стандартный широковещательный адрес
                broadcast_addr = "255.255.255.255"
                sock.sendto(magic_packet, (broadcast_addr, WOL_PORT))
                sock.close()
                logger.info(f"Wake-on-LAN broadcast packet sent to {broadcast_addr}:{WOL_PORT}")
            except Exception as e:
                logger.warning(f"Error sending broadcast WoL packet (non-critical): {str(e)}")
                # Не считаем ошибкой, т.к. основной пакет уже отправлен
                
            return True
            
        except Exception as e:
            logger.error(f"Unexpected error in wake_on_lan: {str(e)}")
            return False
            
    def wait_for_boot(self, max_attempts: int = 30, delay: int = 10) -> bool:
        """Ожидание загрузки Synology NAS"""
        logger.info(f"Waiting for Synology NAS to boot (timeout: {max_attempts * delay}s)...")
        
        for attempt in range(max_attempts):
            # Принудительно проверяем статус без использования кэша
            if self.is_online(force_check=True):
                logger.info(f"Synology NAS is online after {attempt + 1} attempts ({(attempt + 1) * delay}s)")
                
                # Проверяем, что не только сеть доступна, но и API загрузился
                api_ready = False
                logger.info("Waiting for API services to initialize...")
                
                for api_check in range(5):  # Даем еще до 50 секунд для загрузки API
                    if self.sid or self.login():
                        api_ready = True
                        logger.info(f"API services are ready after {api_check + 1} attempts")
                        break
                    logger.debug(f"API not ready yet, waiting... ({api_check + 1}/5)")
                    sleep(10)
                
                if not api_ready:
                    logger.warning("System is online but API services may not be fully initialized")
                    
                # Дадим дополнительное время для полной загрузки всех сервисов
                sleep(delay)
                return True
                
            sleep(delay)
            logger.info(f"Waiting for boot... Attempt {attempt + 1}/{max_attempts}")
            
        logger.error(f"Synology NAS didn't come online after {max_attempts * delay} seconds")
        return False
        
    def power_on(self) -> bool:
        """Включение Synology NAS"""
        # Принудительная проверка статуса
        if self.is_online(force_check=True):
            logger.info("Synology NAS is already online")
            return True
        
        logger.info("Powering on Synology NAS via Wake-on-LAN...")
        
        # Проверяем, настроен ли MAC-адрес
        if not SYNOLOGY_MAC:
            logger.error("Cannot power on: MAC address not configured in settings")
            return False
            
        # Пробуем отправить несколько WoL пакетов для надежности
        success = False
        for attempt in range(3):
            logger.debug(f"Sending WoL packet, attempt {attempt + 1}/3")
            if self.wake_on_lan():
                success = True
                break
            sleep(1)
            
        if not success:
            logger.error("Failed to send Wake-on-LAN packets")
            return False
        
        # Ожидание загрузки
        logger.info("WoL packets sent successfully, waiting for system to boot...")
        boot_result = self.wait_for_boot(max_attempts=30, delay=10)
        
        if boot_result:
            # Проверяем доступность API после загрузки
            system_status = self.get_system_status()
            if system_status.get("status") == "online":
                logger.info("System booted successfully with API access")
                return True
            else:
                logger.warning("System appears to be online but API may not be fully ready")
                return True
        else:
            logger.error("System did not come online after WoL")
            return False
        
    def power_off(self) -> bool:
        """Выключение Synology NAS"""
        if not self.is_online(force_check=True):
            logger.info("Synology NAS is already offline")
            return True
        
        logger.info("Powering off Synology NAS...")
        
        # Список API и методов для попытки выключения
        apis_to_try = [
            {"api": "SYNO.Core.System", "method": "shutdown", "version": 1},
            {"api": "SYNO.DSM.System", "method": "shutdown", "version": 1},
            {"api": SYNOLOGY_POWER_API, "method": "shutdown", "version": SYNOLOGY_API_VERSION}
        ]
        
        # Перебираем все возможные API и методы
        for api_info in apis_to_try:
            try:
                logger.info(f"Trying shutdown with {api_info['api']} API using method {api_info['method']}")
                api_result = self._make_api_request(api_info['api'], api_info['method'], version=api_info['version'])
                if api_result is not None:
                    logger.info(f"Successfully initiated system shutdown using {api_info['api']} API")
                    
                    # Даем системе время начать процесс выключения
                    logger.info("Waiting for shutdown to initialize...")
                    sleep(5)
                    
                    return True
            except Exception as e:
                logger.error(f"Error during shutdown with {api_info['api']}: {str(e)}")
                
        # Если все попытки не удались, возвращаем False
        logger.error("All shutdown attempts failed")
        return False
                
        # Если все еще не сработало, используем оригинальный метод shutdown_system
        if not result:
            result = self.shutdown_system()
        
        if result:
            # Дополнительная проверка, что система действительно выключилась
            logger.info("Verifying system is offline...")
            for attempt in range(12):  # Проверяем в течение 2 минут (12 * 10 сек)
                if not self.is_online(force_check=True):
                    logger.info(f"System confirmed offline after {attempt * 10} seconds")
                    return True
                logger.debug(f"System still shutting down, checking again... ({attempt + 1}/12)")
                sleep(10)
                
            logger.warning("System still appears to be online after shutdown command")
            return False
        else:
            logger.error("Failed to initiate shutdown")
            return False
        
    # Заглушки для расширенных методов
    def get_shared_folders(self) -> List[Dict[str, Any]]:
        """Получение списка общих папок"""
        logger.info("Getting list of shared folders")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for shared folders request")
            return []
            
        try:
            # Запрашиваем список общих папок через FileStation API
            result = self._make_api_request("SYNO.FileStation.List", "list_share", version=2)
            
            if not result:
                # Пробуем альтернативный API
                logger.info("Trying alternative API for shared folders")
                alt_result = self._make_api_request("SYNO.FileStation.List", "list_share", version=1)
                if alt_result:
                    return alt_result.get("shares", [])
                return []
                
            return result.get("shares", [])
            
        except Exception as e:
            logger.error(f"Error getting shared folders: {str(e)}")
            return []
        
    def get_system_load(self) -> Dict[str, Any]:
        """Получение информации о загрузке системы"""
        logger.info("Getting system load information")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for system load request")
            return {}
            
        try:
            # Запрашиваем информацию о загрузке системы
            result = self._make_api_request("SYNO.Core.System.Utilization", "get", version=1)
            
            if not result:
                # Пробуем альтернативный API
                logger.info("Trying alternative API for system load")
                alt_result = self._make_api_request("SYNO.Core.System", "info", version=3)
                
                if not alt_result:
                    return {}
                    
                # Формируем из частичных данных
                return {
                    "cpu_load": alt_result.get("cpu_usage", 0),
                    "memory": {
                        "total": alt_result.get("memory_size", 0),
                        "used": alt_result.get("memory_usage", 0),
                        "usage_percent": alt_result.get("memory_usage_percent", 0)
                    }
                }
                
            # Формируем структурированный результат
            return {
                "cpu_load": result.get("cpu", {}).get("user", 0) + result.get("cpu", {}).get("system", 0),
                "memory": result.get("memory", {}),
                "network": result.get("network", {})
            }
            
        except Exception as e:
            logger.error(f"Error getting system load: {str(e)}")
            return {}
        
    def is_online_api(self) -> bool:
        """Проверка онлайн-статуса Synology NAS с использованием API"""
        if not self.is_online():
            return False
        
        # Проверяем доступность API через авторизацию
        if not self.sid and not self.login():
            return False
        
        return True
        
    def get_storage_status(self) -> Dict[str, Any]:
        """Получение подробной информации о хранилище"""
        logger.info("Getting storage status information")
        
        # Проверяем доступность NAS и API
        if not self.is_online_api():
            logger.error("Cannot get storage status: NAS is not online or API is not accessible")
            return {"error": "authentication_failed"}
            
        try:
            # Пробуем получить информацию о хранилище через SYNO.Storage.CGI.Storage API
            result = self._make_api_request("SYNO.Storage.CGI.Storage", "load_info", version=1)
            
            if not result:
                # Пробуем альтернативный API
                logger.info("Trying alternative API for storage info")
                alt_result = self._make_api_request("SYNO.Core.Storage", "info", version=1)
                
                if not alt_result:
                    # Пробуем еще один альтернативный API
                    logger.info("Trying SYNO.Core.System API for storage info")
                    sys_result = self._make_api_request("SYNO.Core.System", "info", version=3)
                    
                    if not sys_result:
                        return {
                            "volumes": [],
                            "disks": [],
                            "total_size": 0,
                            "total_used": 0,
                            "error": "no_data"
                        }
                    
                    # Извлекаем базовую информацию о хранилище из системной информации
                    return {
                        "volumes": [],
                        "disks": [],
                        "total_size": sys_result.get("hdd_total_size", 0) * 1024**2,  # МБ в байты
                        "total_used": sys_result.get("hdd_total_size", 0) * sys_result.get("hdd_usage", 0) / 100 * 1024**2,
                    }
                
                # Обрабатываем данные из альтернативного API
                volumes = alt_result.get("volumes", [])
                disks = alt_result.get("disks", [])
                
            else:
                # Обрабатываем данные из основного API
                volumes = result.get("volumes", [])
                disks = result.get("disks", [])
            
            # Рассчитываем общие размеры
            total_size = 0
            total_used = 0
            
            for volume in volumes:
                volume_size = volume.get("size", {}).get("total", 0)
                volume_used = volume.get("size", {}).get("used", 0)
                
                total_size += volume_size
                total_used += volume_used
            
            return {
                "volumes": volumes,
                "disks": disks,
                "total_size": total_size,
                "total_used": total_used
            }
            
        except Exception as e:
            logger.error(f"Error in get_storage_status: {str(e)}")
            return {"error": str(e)}
        
    def get_security_status(self) -> Dict[str, Any]:
        """Получение информации о состоянии безопасности"""
        logger.info("Getting security status information")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for security status request")
            return {"success": False, "error": "authentication_failed"}
            
        try:
            # Пробуем получить информацию о безопасности через API Security Scan
            result = self._make_api_request("SYNO.Core.SecurityScan.Status", "get", version=1)
            
            if not result:
                # Пробуем альтернативный API
                logger.info("Trying alternative API for security status")
                # Проверяем статус брандмауэра
                firewall_result = self._make_api_request("SYNO.Core.Security.Firewall.Status", "get", version=1)
                
                # Проверяем статус автоматических обновлений
                update_result = self._make_api_request("SYNO.Core.Upgrade.Server.Setting", "get", version=1)
                
                # Если ни один из API не отвечает
                if not firewall_result and not update_result:
                    # Получаем общую информацию о системе для базовой проверки безопасности
                    sys_result = self._make_api_request("SYNO.DSM.Info", "getinfo", version=2)
                    
                    if not sys_result:
                        return {
                            "success": False,
                            "status": "unknown",
                            "last_check": None,
                            "is_secure": False,
                            "error": "no_security_api"
                        }
                    
                    # Собираем базовые сведения из системной информации
                    return {
                        "success": True,
                        "status": "basic",
                        "last_check": None,
                        "is_secure": True,  # Предполагаем, что система в целом безопасна
                        "firewall_enabled": None,
                        "auto_update": None,
                        "version_latest": sys_result.get("version_string", "")
                    }
                
                # Собираем информацию из доступных результатов
                firewall_enabled = firewall_result.get("enabled", False) if firewall_result else None
                auto_update = update_result.get("auto_update", False) if update_result else None
                
                # Определяем, насколько система безопасна
                is_secure = True  # По умолчанию предполагаем, что система безопасна
                if firewall_enabled is not None and not firewall_enabled:
                    is_secure = False
                
                return {
                    "success": True,
                    "status": "partial",
                    "last_check": None,
                    "is_secure": is_secure,
                    "firewall_enabled": firewall_enabled,
                    "auto_update": auto_update
                }
            
            # Если основное API отвечает, возвращаем его данные
            return {
                "success": True,
                "status": result.get("status", "unknown"),
                "last_check": result.get("last_check", None),
                "is_secure": result.get("is_secure", False),
                "details": result.get("details", {})
            }
            
        except Exception as e:
            logger.error(f"Error in get_security_status: {str(e)}")
            return {"success": False, "error": str(e)}

    def get_processes(self, limit: int = 20) -> List[Dict[str, Any]]:
        """Получение списка активных процессов"""
        logger.info(f"Getting list of active processes (limit={limit})")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for processes request")
            return []
            
        try:
            # Получаем список процессов через API
            result = self._make_api_request("SYNO.Core.System.Process", "list", version=1, 
                                           params={"sort_by": "cpu", "order": "DESC", "limit": limit})
            
            if not result:
                logger.warning("Failed to get process list")
                return []
                
            return result.get("processes", [])
            
        except Exception as e:
            logger.error(f"Error getting process list: {str(e)}")
            return []

    def get_network_status(self) -> Dict[str, Any]:
        """Получение информации о сетевых подключениях"""
        logger.info("Getting network status information")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for network status request")
            return {}
            
        try:
            # Получаем информацию о сетевых интерфейсах
            interface_result = self._make_api_request("SYNO.Core.Network.Interface", "list", version=1)
            
            # Получаем статистику использования сети
            utilization_result = self._make_api_request("SYNO.Core.System.Utilization", "get", version=1)
            
            interfaces = []
            if interface_result:
                interfaces = interface_result.get("interfaces", [])
                
            network_stats = {}
            if utilization_result and "network" in utilization_result:
                network_stats = utilization_result.get("network", {})
                
            # Объединяем данные
            for interface in interfaces:
                iface_id = interface.get("id", "")
                if iface_id in network_stats:
                    interface["rx"] = network_stats[iface_id].get("rx", 0)
                    interface["tx"] = network_stats[iface_id].get("tx", 0)
            
            return {
                "interfaces": interfaces,
                "statistics": network_stats
            }
            
        except Exception as e:
            logger.error(f"Error getting network status: {str(e)}")
            return {}

    def get_system_logs(self, limit: int = 20) -> List[Dict[str, Any]]:
        """Получение журналов системы"""
        logger.info(f"Getting system logs (limit={limit})")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for system logs request")
            return []
            
        try:
            # Получаем журналы через API
            result = self._make_api_request("SYNO.Core.SyslogClient.Log", "list", version=1, 
                                           params={"start": 0, "limit": limit, "sort": "time", "dir": "DESC"})
            
            if not result:
                # Пробуем альтернативный API
                logger.info("Trying alternative API for system logs")
                alt_result = self._make_api_request("SYNO.Core.Log", "list", version=1,
                                                  params={"start": 0, "limit": limit, "sort": "time", "dir": "DESC"})
                
                if alt_result:
                    return alt_result.get("logs", [])
                return []
                
            return result.get("logs", [])
            
        except Exception as e:
            logger.error(f"Error getting system logs: {str(e)}")
            return []

    def get_power_schedule(self) -> Dict[str, Any]:
        """Получение расписания включения/выключения"""
        logger.info("Getting power schedule")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for power schedule request")
            return {}
            
        try:
            # Получаем расписание через API
            result = self._make_api_request("SYNO.Core.Hardware.PowerSchedule", "get", version=1)
            
            if not result:
                return {}
                
            return result
            
        except Exception as e:
            logger.error(f"Error getting power schedule: {str(e)}")
            return {}

    def set_power_schedule(self, schedule_type: str, days: List[int], time: str, enabled: bool = True) -> bool:
        """Настройка расписания включения/выключения
        
        Args:
            schedule_type: Тип расписания ('boot' или 'shutdown')
            days: Список дней недели (0-6, где 0 - понедельник)
            time: Время в формате 'HH:MM'
            enabled: Включить или выключить расписание
            
        Returns:
            True если успешно, False в противном случае
        """
        logger.info(f"Setting power schedule for {schedule_type} at {time} on days {days}")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for setting power schedule")
            return False
            
        try:
            # Получаем текущее расписание
            current_schedule = self._make_api_request("SYNO.Core.Hardware.PowerSchedule", "get", version=1)
            
            if not current_schedule:
                logger.error("Failed to get current power schedule")
                return False
                
            # Подготавливаем новое расписание
            params = {
                "enabled": enabled,
                "type": schedule_type,
                "day": days,
                "time": time
            }
            
            # Устанавливаем новое расписание
            result = self._make_api_request("SYNO.Core.Hardware.PowerSchedule", "set", version=1, params=params)
            
            if not result:
                logger.error("Failed to set power schedule")
                return False
                
            logger.info(f"Power schedule for {schedule_type} set successfully")
            return True
            
        except Exception as e:
            logger.error(f"Error setting power schedule: {str(e)}")
            return False

    def get_temperature_status(self) -> Dict[str, Any]:
        """Получение информации о температуре системы и дисков"""
        logger.info("Getting temperature status")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for temperature status request")
            return {}
            
        try:
            # Получаем информацию о системе для общей температуры
            system_info = self._make_api_request("SYNO.DSM.Info", "getinfo", version=2)
            
            # Получаем информацию о дисках для их температуры
            storage_info = self._make_api_request("SYNO.Storage.CGI.Storage", "load_info", version=1)
            
            system_temp = None
            disk_temps = []
            
            if system_info:
                system_temp = system_info.get("temperature")
            
            if storage_info:
                disks = storage_info.get("disks", [])
                for disk in disks:
                    name = disk.get("name", "unknown")
                    model = disk.get("model", "unknown")
                    temp = disk.get("temp", None)
                    if temp is not None:
                        disk_temps.append({
                            "name": name,
                            "model": model,
                            "temperature": temp
                        })
            
            return {
                "system_temperature": system_temp,
                "disk_temperatures": disk_temps,
                "warning": system_info.get("temperature_warn", False) if system_info else False
            }
            
        except Exception as e:
            logger.error(f"Error getting temperature status: {str(e)}")
            return {}

    def browse_files(self, folder_path: str = "", limit: int = 100) -> Dict[str, Any]:
        """Просмотр файлов в указанной директории
        
        Args:
            folder_path: Путь к папке (пустая строка для корневых общих папок)
            limit: Максимальное количество элементов для возврата
            
        Returns:
            Словарь с информацией о файлах и папках
        """
        logger.info(f"Browsing files in {folder_path or 'root'}")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for file browsing")
            return {"success": False, "error": "authentication_failed"}
            
        try:
            if not folder_path:
                # Если путь не указан, получаем список общих папок
                result = self._make_api_request("SYNO.FileStation.List", "list_share", version=2)
                
                if not result:
                    logger.error("Failed to list shared folders")
                    return {"success": False, "error": "api_error"}
                
                return {
                    "success": True,
                    "items": result.get("shares", []),
                    "path": "",
                    "is_root": True
                }
            else:
                # Получаем список файлов в указанной директории
                params = {
                    "folder_path": folder_path,
                    "limit": limit,
                    "offset": 0,
                    "sort_by": "name",
                    "sort_direction": "ASC"
                }
                
                result = self._make_api_request("SYNO.FileStation.List", "list", version=2, params=params)
                
                if not result:
                    logger.error(f"Failed to list files in {folder_path}")
                    return {"success": False, "error": "api_error"}
                
                return {
                    "success": True,
                    "items": result.get("files", []),
                    "path": folder_path,
                    "is_root": False,
                    "total": result.get("total", 0)
                }
                
        except Exception as e:
            logger.error(f"Error browsing files: {str(e)}")
            return {"success": False, "error": str(e)}

    def manage_service(self, service_name: str, action: str = "status") -> Dict[str, Any]:
        """Управление системным сервисом
        
        Args:
            service_name: Имя сервиса
            action: Действие (status/start/stop/restart)
            
        Returns:
            Словарь с результатом операции
        """
        logger.info(f"Managing service {service_name}, action: {action}")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for service management")
            return {"success": False, "error": "authentication_failed"}
            
        try:
            # Проверяем доступное API для управления сервисами
            if action == "status":
                result = self._make_api_request("SYNO.Core.Service", "get", version=1, 
                                              params={"service": service_name})
            else:
                result = self._make_api_request("SYNO.Core.Service", action, version=1, 
                                              params={"service": service_name})
            
            if not result:
                logger.error(f"Failed to {action} service {service_name}")
                return {"success": False, "error": "api_error"}
                
            return {
                "success": True,
                "service": service_name,
                "action": action,
                "result": result,
                "status": result.get("status") if action == "status" else "completed"
            }
            
        except Exception as e:
            logger.error(f"Error managing service {service_name}: {str(e)}")
            return {"success": False, "error": str(e)}

    def search_files(self, pattern: str, folder_path: str = "", limit: int = 100) -> Dict[str, Any]:
        """Поиск файлов по шаблону
        
        Args:
            pattern: Шаблон для поиска
            folder_path: Путь к папке для поиска (пустая строка для всех общих папок)
            limit: Максимальное количество результатов
            
        Returns:
            Словарь с найденными файлами
        """
        logger.info(f"Searching for {pattern} in {folder_path or 'all shared folders'}")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for file search")
            return {"success": False, "error": "authentication_failed"}
            
        try:
            if not folder_path:
                # Получаем список всех общих папок для поиска
                shares_result = self._make_api_request("SYNO.FileStation.List", "list_share", version=2)
                
                if not shares_result:
                    logger.error("Failed to list shared folders for search")
                    return {"success": False, "error": "api_error"}
                
                # Формируем список путей для поиска
                folder_paths = [share.get("path") for share in shares_result.get("shares", [])]
            else:
                folder_paths = [folder_path]
            
            # Запускаем поиск
            params = {
                "folder_path": folder_paths,
                "pattern": pattern,
                "limit": limit,
                "offset": 0
            }
            
            result = self._make_api_request("SYNO.FileStation.Search", "start", version=2, params=params)
            
            if not result:
                logger.error(f"Failed to start search for {pattern}")
                return {"success": False, "error": "api_error"}
            
            # Получаем taskid для проверки результатов
            taskid = result.get("taskid")
            if not taskid:
                logger.error("No taskid received for search")
                return {"success": False, "error": "no_task_id"}
            
            # Ожидаем завершения поиска
            search_result = {"finished": False, "progress": 0}
            for _ in range(10):  # Максимум 10 попыток
                search_status = self._make_api_request("SYNO.FileStation.Search", "status", version=2, 
                                                    params={"taskid": taskid})
                
                if not search_status:
                    break
                    
                search_result["progress"] = search_status.get("progress", 0)
                
                if search_status.get("finished", False):
                    search_result["finished"] = True
                    break
                    
                time.sleep(0.5)  # Пауза между запросами
            
            # Получаем результаты поиска
            if search_result["finished"]:
                list_result = self._make_api_request("SYNO.FileStation.Search", "list", version=2, 
                                                   params={"taskid": taskid, "limit": limit})
                
                if list_result:
                    files = list_result.get("files", [])
                    return {
                        "success": True,
                        "pattern": pattern,
                        "results": files,
                        "total": list_result.get("total", len(files))
                    }
            
            # Если не удалось получить результаты, останавливаем поиск
            self._make_api_request("SYNO.FileStation.Search", "stop", version=2, 
                                 params={"taskid": taskid})
            
            return {
                "success": False,
                "error": "search_timeout",
                "progress": search_result["progress"]
            }
            
        except Exception as e:
            logger.error(f"Error searching files: {str(e)}")
            return {"success": False, "error": str(e)}

    def get_backup_status(self) -> Dict[str, Any]:
        """Получение информации о резервном копировании"""
        logger.info("Getting backup status information")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for backup status request")
            return {"success": False, "error": "authentication_failed"}
            
        try:
            # Пробуем получить информацию о Hyper Backup
            hyper_result = self._make_api_request("SYNO.Backup.Repository", "list", version=1)
            
            # Пробуем получить информацию о задачах Time Backup
            time_result = self._make_api_request("SYNO.BackupService.Task", "list", version=1)
            
            # Проверяем статус резервного копирования USB
            usb_result = self._make_api_request("SYNO.USBCopy", "status", version=1)
            
            backups = {
                "hyper_backup": hyper_result.get("backups", []) if hyper_result else [],
                "time_backup": time_result.get("tasks", []) if time_result else [],
                "usb_copy": {"enabled": usb_result.get("enable", False) if usb_result else False}
            }
            
            return {
                "success": True,
                "backups": backups,
                "available_apis": {
                    "hyper_backup": hyper_result is not None,
                    "time_backup": time_result is not None,
                    "usb_copy": usb_result is not None
                }
            }
            
        except Exception as e:
            logger.error(f"Error getting backup status: {str(e)}")
            return {"success": False, "error": str(e)}

    def check_for_updates(self) -> Dict[str, Any]:
        """Проверка наличия обновлений системы"""
        logger.info("Checking for system updates")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for update check")
            return {"success": False, "error": "authentication_failed"}
            
        try:
            # Получаем текущую информацию о системе
            system_info = self._make_api_request("SYNO.DSM.Info", "getinfo", version=2)
            
            if not system_info:
                logger.error("Failed to get system info for update check")
                return {"success": False, "error": "api_error"}
            
            # Проверяем наличие обновлений
            update_result = self._make_api_request("SYNO.Core.Upgrade.Server", "check", version=1)
            
            # Получаем настройки автоматического обновления
            settings_result = self._make_api_request("SYNO.Core.Upgrade.Server.Setting", "get", version=1)
            
            # Получаем информацию о доступных обновлениях
            update_info = self._make_api_request("SYNO.Core.Upgrade.Server.Download", "list", version=1)
            
            current_version = system_info.get("version_string", "unknown")
            auto_update_enabled = settings_result.get("auto_update", False) if settings_result else False
            
            updates = []
            if update_info and "updates" in update_info:
                updates = update_info.get("updates", [])
            
            update_available = len(updates) > 0
            
            return {
                "success": True,
                "current_version": current_version,
                "update_available": update_available,
                "auto_update_enabled": auto_update_enabled,
                "updates": updates
            }
            
        except Exception as e:
            logger.error(f"Error checking for updates: {str(e)}")
            return {"success": False, "error": str(e)}

    def get_quota_info(self) -> Dict[str, Any]:
        """Получение информации о квотах пользователей"""
        logger.info("Getting user quota information")
        
        # Аутентифицируемся перед запросом данных
        if not self.sid and not self.login():
            logger.error("Failed to authenticate for quota info request")
            return {"success": False, "error": "authentication_failed"}
            
        try:
            # Получаем список пользователей
            users_result = self._make_api_request("SYNO.Core.User", "list", version=1)
            
            if not users_result:
                logger.error("Failed to get user list for quota info")
                return {"success": False, "error": "api_error"}
            
            users = users_result.get("users", [])
            user_quotas = []
            
            # Получаем квоты для каждого пользователя
            for user in users:
                user_name = user.get("name")
                if not user_name:
                    continue
                    
                quota_result = self._make_api_request("SYNO.Core.Quota", "get", version=1, 
                                                   params={"user_name": user_name})
                
                if quota_result and "quotas" in quota_result:
                    user_quotas.append({
                        "user": user_name,
                        "quotas": quota_result.get("quotas", [])
                    })
            
            return {
                "success": True,
                "user_quotas": user_quotas
            }
            
        except Exception as e:
            logger.error(f"Error getting quota info: {str(e)}")
            return {"success": False, "error": str(e)}
