"""
Network client for connecting to domains and central server.
"""
import os
import json
import time
import uuid
import base64
import requests
from urllib.parse import urljoin
import threading
from datetime import datetime

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from ...shared.utils import setup_logging, get_local_ip
from ...shared.domain import Domain
from ...shared.ddns import DDNS
from ...shared.constants import (
    DEFAULT_PORT, DEFAULT_CENTRAL_SERVER_PORT, DEFAULT_REGISTRY_REFRESH,
    CMD_SOURCES, CMD_DOWNLOAD, CMD_P2P, CMD_VISIT, CMD_HELP
)

# Setup logger
logger = setup_logging('network_client')

class NetworkClient:
    """Client for network operations including domain connections and central server communication."""
    
    def __init__(self, security_manager, ddns, central_server_host, central_server_port=DEFAULT_CENTRAL_SERVER_PORT):
        """Initialize the network client."""
        self.security_manager = security_manager
        self.ddns = ddns
        self.central_server_url = f"http://{central_server_host}:{central_server_port}"
        
        # Active PFS sessions
        self.pfs_sessions = {}
        
        # Active downloads
        self.downloads = {}
        
        # Domain registry cache
        self.domain_cache = {}
        self.last_refresh = 0
        
        # For P2P messaging
        self.message_history = {}
        
        # Client ID
        self.client_id = str(uuid.uuid4())
    def request_file_key(self, domain_name, file_name):
        """Request a decryption key for a file from a domain."""
        try:
            # First, resolve the domain to get IP and port
            success, result = self.resolve_domain(domain_name)
            if not success:
                return False, f"Could not resolve domain: {result}"
            
            ip, port = result
            
            # Construct the URL
            url = f"http://{ip}:{port}/key?file={file_name}"
            
            # Make the request
            response = requests.get(url, timeout=10)
            
            if response.status_code == 200:
                # Parse the response
                try:
                    data = response.json()
                    if data.get('success'):
                        # Key should be base64 encoded
                        encrypted_key = data.get('key')
                        return True, base64.b64decode(encrypted_key)
                    else:
                        return False, data.get('error', 'Unknown error')
                except json.JSONDecodeError:
                    return False, "Invalid response from server"
            else:
                return False, f"HTTP error: {response.status_code}"
        except Exception as e:
            logger.error(f"Error requesting file key: {str(e)}")
            return False, f"Error: {str(e)}"
    
    def check_domain_availability(self, domain):
        
        domain_name = domain
        if isinstance(domain, Domain):
            domain_name = domain.full_name
        
        # Query the central registration server
        try:
            # Construct the query URL
            query_url = f"http://jcmc.serveminecraft.net/cent.php?check={domain_name}"
            
            # Send the request
            response = requests.get(query_url, timeout=10)
            
            if response.status_code == 200:
                # Parse the response
                try:
                    data = response.json()
                    if data.get('available') is True:
                        return True, "Domain is available"
                    else:
                        reason = data.get('reason', 'Domain is already taken')
                        return False, reason
                except json.JSONDecodeError:
                    # Check for simple text response
                    text = response.text.strip().lower()
                    if "available" in text:
                        return True, "Domain is available"
                    else:
                        return False, f"Domain is unavailable: {text}"
            else:
                logger.error(f"Error checking domain availability: HTTP {response.status_code}")
                return False, f"Error checking domain: HTTP {response.status_code}"
                
        except requests.RequestException as e:
            logger.error(f"Network error checking domain availability: {str(e)}")
            return False, f"Network error: {str(e)}"
        
        # Fallback (if we reach here, something unexpected happened)
        return False, "Could not determine domain availability"
    
    def sync_domains_with_central_server(self):
        
        try:
            # Get local domains from DDNS
            local_domains = self.ddns.list_entries()
            
            # Convert to format expected by central server
            domains_to_sync = {}
            for domain_name, entry in local_domains.items():
                domains_to_sync[domain_name] = {
                    'ip': entry['ip'],
                    'port': entry['port'],
                    'last_seen': entry.get('updated', time.time())
                }
            
            # Send to central server
            sync_url = "http://jcmc.serveminecraft.net/cent.php?sync=1"
            
            # Convert domains to JSON
            domains_json = json.dumps(domains_to_sync)
            
            # Send the request
            response = requests.post(
                sync_url,
                data={'domains': domains_json},
                timeout=15
            )
            
            if response.status_code == 200:
                try:
                    data = response.json()
                    if data.get('success'):
                        # Process returned domains
                        central_domains = data.get('domains', {})
                        domains_added = 0
                        
                        for domain_name, domain_info in central_domains.items():
                            if domain_name not in local_domains:
                                # Add to local DDNS
                                self.ddns.add_entry(
                                    domain_name,
                                    domain_info['ip'],
                                    domain_info['port']
                                )
                                domains_added += 1
                        
                        logger.info(f"Domain sync completed: {domains_added} domains added locally")
                        return True, f"Sync successful: {domains_added} domains added"
                    else:
                        error = data.get('error', 'Unknown error')
                        logger.error(f"Sync failed: {error}")
                        return False, f"Sync failed: {error}"
                except json.JSONDecodeError:
                    logger.error("Failed to parse sync response")
                    return False, "Failed to parse server response"
            else:
                logger.error(f"Sync request failed: HTTP {response.status_code}")
                return False, f"Sync failed: HTTP {response.status_code}"
                
        except Exception as e:
            logger.error(f"Error during domain sync: {str(e)}")
            return False, f"Sync error: {str(e)}"
    
    def register_domain(self, domain):
        
        try:
            # Prepare domain data
            domain_name = domain.full_name
            domain_data = domain.to_dict()
            
            # Log registration attempt
            logger.info(f"Attempting to register domain: {domain_name}")
            
            # Direct registration with central server
            register_url = f"http://jcmc.serveminecraft.net/cent.php?register={domain_name}&ip={domain.ip}&port={domain.port}"
            if domain.title:
                register_url += f"&title={domain.title}"
            
            # Log the URL
            logger.info(f"Registration URL: {register_url}")
            
            # Send request directly to central server
            try:
                response = requests.get(register_url, timeout=15)
                
                # Log the response
                logger.info(f"Central server response code: {response.status_code}")
                logger.info(f"Central server response text: {response.text[:200]}")
                
                if response.status_code == 200:
                    try:
                        data = response.json()
                        if data.get('success'):
                            logger.info(f"Domain {domain_name} registered successfully with central server")
                            return True, data.get('message', 'Success')
                        else:
                            logger.error(f"Failed to register with central server: {data.get('error', 'Unknown error')}")
                            return False, data.get('error', 'Unknown error')
                    except json.JSONDecodeError:
                        # Check if response contains "success"
                        if "success" in response.text.lower():
                            logger.info(f"Domain {domain_name} registered successfully (text response)")
                            return True, "Success (text response)"
                        else:
                            logger.error(f"Failed to register: {response.text}")
                            return False, f"Registration failed: {response.text}"
                else:
                    logger.error(f"Failed to register domain: HTTP {response.status_code}")
                    return False, f"HTTP Error: {response.status_code}"
            except requests.RequestException as e:
                logger.error(f"Network error registering with central server: {str(e)}")
                return False, f"Network error: {str(e)}"
                
        except Exception as e:
            logger.error(f"Unexpected error registering domain: {str(e)}")
            return False, f"Error: {str(e)}"

    def unregister_domain(self, domain_name):
        """Unregister a domain from the central server."""
        try:
            logger.info(f"Attempting to unregister domain: {domain_name}")
            
            # Fix: Use the correct endpoint format with query parameters
            unregister_url = f"http://jcmc.serveminecraft.net/cent.php?unregister={domain_name}&force=1"
            
            # Log the URL for debugging
            logger.info(f"Unregistration URL: {unregister_url}")
            
            # Use GET instead of POST
            response = requests.get(
                unregister_url,
                timeout=15
            )
            
            # Log the response
            logger.info(f"Central server response code: {response.status_code}")
            logger.info(f"Central server response text: {response.text[:200]}")
            
            if response.status_code == 200:
                try:
                    data = response.json()
                    unregister_success = data.get('success', False)
                    if unregister_success:
                        logger.info(f"Domain {domain_name} unregistered successfully from central server")
                        
                        # Always try to remove from local DDNS
                        local_result = self.ddns.remove_entry(domain_name)
                        
                        if local_result[0]:
                            logger.info(f"Domain {domain_name} removed from local DDNS")
                            return True, "Domain unregistered successfully"
                        else:
                            return True, "Domain unregistered from central server but could not be removed locally"
                    else:
                        error_msg = data.get('error', 'Unknown error')
                        logger.warning(f"Could not unregister from central server: {error_msg}")
                        return False, error_msg
                except json.JSONDecodeError:
                    # Fallback for text response
                    if "success" in response.text.lower():
                        unregister_success = True
                        logger.info(f"Domain {domain_name} unregistered successfully (text response)")
                        
                        # Remove from local DDNS
                        local_result = self.ddns.remove_entry(domain_name)
                        if local_result[0]:
                            return True, "Domain unregistered successfully"
                        else:
                            return True, "Domain unregistered from central server but could not be removed locally"
                    else:
                        logger.warning(f"Could not unregister from central server: {response.text}")
                        return False, f"Unregistration failed: {response.text}"
            else:
                logger.warning(f"Could not unregister from central server: HTTP {response.status_code}")
                return False, f"HTTP Error: {response.status_code}"
                
        except Exception as e:
            logger.error(f"Unexpected error unregistering domain: {str(e)}")
            return False, f"Error: {str(e)}"
    
    def update_domain(self, domain_name, **kwargs):
        """Update domain information on the central server."""
        try:
            logger.info(f"Updating domain {domain_name} with {kwargs}")
            
            # Fix: Use the correct URL format for cent.php
            update_url = f"http://jcmc.serveminecraft.net/cent.php?update={domain_name}"
            
            # Add each parameter to the URL
            for key, value in kwargs.items():
                update_url += f"&{key}={value}"
            
            # Log the URL for debugging
            logger.info(f"Update URL: {update_url}")
            
            # Use GET instead of POST
            response = requests.get(
                update_url,
                timeout=15
            )
            
            # Log the response
            logger.info(f"Central server response code: {response.status_code}")
            logger.info(f"Central server response text: {response.text[:200]}")
            
            if response.status_code == 200:
                try:
                    data = response.json()
                    if data.get('success'):
                        logger.info(f"Domain {domain_name} updated successfully")
                        return True, "Domain updated successfully"
                    else:
                        error_msg = data.get('error', 'Unknown error')
                        logger.warning(f"Failed to update domain: {error_msg}")
                        return False, error_msg
                except json.JSONDecodeError:
                    # Fallback for text response
                    if "success" in response.text.lower():
                        logger.info(f"Domain {domain_name} updated successfully (text response)")
                        return True, "Domain updated successfully"
                    else:
                        logger.warning(f"Failed to update domain: {response.text}")
                        return False, f"Update failed: {response.text}"
            else:
                logger.warning(f"Failed to update domain: HTTP {response.status_code}")
                return False, f"HTTP Error: {response.status_code}"
                
        except Exception as e:
            logger.error(f"Unexpected error updating domain: {str(e)}")
            return False, f"Error: {str(e)}"
    
    def get_sources(self, force_refresh=False):
        """Get list of available domains from the central server."""
        # Check if we should use cached data
        now = time.time()
        if not force_refresh and self.domain_cache and (now - self.last_refresh) < DEFAULT_REGISTRY_REFRESH:
            return True, self.domain_cache
        
        try:
            # FIXING THE URL: Change from API format to cent.php format
            response = requests.get(
                f"http://jcmc.serveminecraft.net/cent.php?list=1",
                timeout=10
            )
            
            if response.status_code == 200:
                data = response.json()
                if data.get('success'):
                    # FIXING DATA STRUCTURE: cent.php returns domains as a dictionary, not array
                    domains_data = data.get('domains', {})
                    
                    # Convert to Domain objects
                    domain_objects = {}
                    for domain_name, domain_info in domains_data.items():
                        # Parse domain parts from the full name
                        parts = domain_name.split('.')
                        if len(parts) == 4 and parts[3] == 'domain':
                            domain = Domain(
                                prefix=parts[0],
                                main=parts[1],
                                suffix=parts[2],
                                ip=domain_info.get('ip'),
                                port=domain_info.get('port')
                            )
                            # Add other properties
                            domain.title = domain_info.get('title', '')
                            domain.last_seen = domain_info.get('last_seen', '')
                            domain.file_count = domain_info.get('file_count', 0)
                            domain_objects[domain_name] = domain
                    
                    # Update cache
                    self.domain_cache = domain_objects
                    self.last_refresh = now
                    
                    logger.info(f"Retrieved {len(domain_objects)} domains from central server")
                    return True, domain_objects
                else:
                    logger.error(f"Failed to get sources: {data.get('error', 'Unknown error')}")
                    return False, data.get('error', 'Unknown error')
            else:
                logger.error(f"Failed to get sources: HTTP {response.status_code}")
                return False, f"HTTP Error: {response.status_code}"
            
        except requests.RequestException as e:
            logger.error(f"Network error getting sources: {str(e)}")
            return False, f"Network error: {str(e)}"
    
    def resolve_domain(self, domain_name, use_central_server=False):
        """Resolve a domain name to IP and port."""
        # First try local DDNS
        ip, port = self.ddns.resolve(domain_name)
        
        if ip and port:
            return True, (ip, port)
        
        # If not found and use_central_server is True, try central server
        if use_central_server:
            try:
                response = requests.get(
                    urljoin(self.central_server_url, f'api/resolve/{domain_name}'),
                    timeout=10
                )
                
                if response.status_code == 200:
                    data = response.json()
                    if data.get('success'):
                        ip = data.get('ip')
                        port = data.get('port')
                        
                        if ip and port:
                            # Add to local DDNS
                            self.ddns.add_entry(domain_name, ip, port)
                            
                            return True, (ip, port)
                        else:
                            logger.error(f"Invalid IP or port from central server")
                            return False, "Invalid IP or port from central server"
                    else:
                        logger.error(f"Failed to resolve domain: {data.get('error', 'Unknown error')}")
                        return False, data.get('error', 'Unknown error')
                else:
                    logger.error(f"Failed to resolve domain: HTTP {response.status_code}")
                    return False, f"HTTP Error: {response.status_code}"
                
            except requests.RequestException as e:
                logger.error(f"Network error resolving domain: {str(e)}")
                return False, f"Network error: {str(e)}"
        
        return False, f"Domain {domain_name} not found in local DDNS"
    
    def get_domain_info(self, domain_name):
        """Get information about a domain."""
        # Resolve domain
        success, result = self.resolve_domain(domain_name)
        if not success:
            return False, result
        
        ip, port = result
        
        try:
            response = requests.get(
                f"http://{ip}:{port}/info",
                timeout=10
            )
            
            if response.status_code == 200:
                data = response.json()
                return True, data
            else:
                logger.error(f"Failed to get domain info: HTTP {response.status_code}")
                return False, f"HTTP Error: {response.status_code}"
            
        except requests.RequestException as e:
            logger.error(f"Network error getting domain info: {str(e)}")
            return False, f"Network error: {str(e)}"
    
    def pfs_initiate(self, domain_name):
        """Initiate a PFS session with a domain."""
        # Resolve domain
        success, result = self.resolve_domain(domain_name)
        if not success:
            return False, result
        
        ip, port = result
        
        try:
            # Send PFS init request
            response = requests.post(
                f"http://{ip}:{port}/pfs/init",
                json={'client_id': self.client_id},
                timeout=10
            )
            
            if response.status_code == 200:
                data = response.json()
                session_id = data.get('session_id')
                public_key_pem = data.get('public_key')
                
                if not session_id or not public_key_pem:
                    logger.error("Missing session ID or public key in PFS init response")
                    return False, "Missing session ID or public key in response"
                
                # Load public key
                public_key = serialization.load_pem_public_key(public_key_pem.encode())
                
                # Create session
                session = {
                    'domain': domain_name,
                    'session_id': session_id,
                    'server_public_key': public_key,
                    'established': False
                }
                
                # Store session
                self.pfs_sessions[domain_name] = session
                
                # Generate our key pair and shared secret
                client_session = self.security_manager.pfs_init()
                session.update(client_session)
                
                # Encrypt shared secret with server's public key
                shared_secret = self.security_manager.generate_aes_key()
                encrypted_secret = public_key.encrypt(
                    shared_secret,
                    padding.OAEP(
                        mgf=padding.MGF1(algorithm=hashes.SHA256()),
                        algorithm=hashes.SHA256(),
                        label=None
                    )
                )
                
                # Send encrypted secret
                exchange_response = requests.post(
                    f"http://{ip}:{port}/pfs/exchange",
                    json={
                        'client_id': self.client_id,
                        'session_id': session_id,
                        'encrypted_secret': base64.b64encode(encrypted_secret).decode()
                    },
                    timeout=10
                )
                
                if exchange_response.status_code == 200:
                    exchange_data = exchange_response.json()
                    if exchange_data.get('success'):
                        # Complete session setup
                        session['shared_secret'] = shared_secret
                        session['established'] = True
                        
                        logger.info(f"PFS session established with {domain_name}")
                        return True, session
                    else:
                        logger.error(f"PFS exchange failed: {exchange_data.get('message', 'Unknown error')}")
                        return False, exchange_data.get('message', 'Unknown error')
                else:
                    logger.error(f"PFS exchange failed: HTTP {exchange_response.status_code}")
                    return False, f"HTTP Error in exchange: {exchange_response.status_code}"
                
            else:
                logger.error(f"PFS initiation failed: HTTP {response.status_code}")
                return False, f"HTTP Error: {response.status_code}"
            
        except requests.RequestException as e:
            logger.error(f"Network error in PFS initiation: {str(e)}")
            return False, f"Network error: {str(e)}"
    
    def download_file(self, domain_name, file_name, download_dir=None):
        """
        Download a file from a domain.
        
        Args:
            domain_name (str): The domain to download from
            file_name (str): The name of the file to download
            download_dir (str, optional): Directory to save the downloaded file.
                If None, will use the default downloads directory.
        
        Returns:
            tuple: (success, result) where result is the file path if successful
                or an error message if not.
        """
        try:
            logger.info(f"Attempting to download {file_name} from {domain_name}")
            
            # Resolve domain to get IP and port
            success, result = self.resolve_domain(domain_name)
            if not success:
                return False, f"Could not resolve domain: {result}"
            
            ip, port = result
            
            # Create URL for file download
            url = f"http://{ip}:{port}/file/{file_name}"
            
            # Determine download directory
            if download_dir is None:
                # Use default downloads directory
                from pathlib import Path
                download_dir = os.path.join(get_data_dir(), 'downloads')
            
            # Create the directory if it doesn't exist
            os.makedirs(download_dir, exist_ok=True)
            
            # Full path to save file
            file_path = os.path.join(download_dir, file_name)
            
            # Download the file
            response = requests.get(url, stream=True, timeout=30)
            
            if response.status_code == 200:
                with open(file_path, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:  # filter out keep-alive new chunks
                            f.write(chunk)
                
                logger.info(f"Download completed: {file_name}")
                return True, file_path
            else:
                logger.error(f"Download failed: HTTP {response.status_code}")
                return False, f"HTTP Error: {response.status_code}"
        
        except Exception as e:
            logger.error(f"Error downloading file: {str(e)}")
            return False, f"Error: {str(e)}"
    
    def _download_file_thread(self, download_id, url, session, save_dir, file_path):
        """Background thread for downloading a file."""
        download = self.downloads.get(download_id)
        if not download:
            return
        
        try:
            # Download file
            response = requests.get(url, stream=True, timeout=60)
            
            if response.status_code != 200:
                download['status'] = 'failed'
                download['error'] = f"HTTP Error: {response.status_code}"
                logger.error(f"Download failed: HTTP {response.status_code}")
                return
            
            # Get file size
            file_size = int(response.headers.get('Content-Length', 0))
            download['total_size'] = file_size
            
            # Create local file path
            file_name = os.path.basename(file_path)
            local_path = os.path.join(save_dir, file_name)
            os.makedirs(os.path.dirname(local_path), exist_ok=True)
            
            
            # Check if encryption key is provided
            encryption_key = None
            if 'X-Encryption-Key' in response.headers:
                try:
                    encrypted_key = base64.b64decode(response.headers['X-Encryption-Key'])
                    
                    # Store the key in keychain
                    success, key_id_or_error = self.security_manager.keychain_manager.receive_encrypted_key(
                        encrypted_key, 
                        domain_name, 
                        file_path
                    )
                    
                    if success:
                        # Retrieve the decrypted key
                        success, encryption_key = self.security_manager.keychain_manager.get_key_for_file(file_path)
                        if not success:
                            logger.error(f"Error retrieving key from keychain: {encryption_key}")
                    else:
                        logger.error(f"Error storing encrypted key in keychain: {key_id_or_error}")
                except Exception as e:
                    logger.error(f"Error processing encryption key: {str(e)}")
            
            # Download file
            with open(local_path, 'wb') as f:
                downloaded = 0
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        # Write chunk
                        f.write(chunk)
                        
                        # Update progress
                        downloaded += len(chunk)
                        if file_size > 0:
                            download['progress'] = (downloaded / file_size) * 100
            
            # Decrypt file if encryption key provided
            if encryption_key:
                try:
                    # Read encrypted data
                    with open(local_path, 'rb') as f:
                        encrypted_data = f.read()
                    
                    # Decrypt using the provided key (not session key)
                    decrypted_data = self.security_manager.decrypt_with_aes(encryption_key, encrypted_data)
                    
                    # Write decrypted data
                    decrypted_path = os.path.splitext(local_path)[0] if local_path.endswith('.enc') else local_path
                    with open(decrypted_path, 'wb') as f:
                        f.write(decrypted_data)
                    
                    # Remove encrypted file
                    if decrypted_path != local_path:
                        os.remove(local_path)
                    
                    # Update download record
                    download['decrypted_path'] = decrypted_path
                    local_path = decrypted_path
                except Exception as e:
                    logger.error(f"Error decrypting file: {str(e)}")
                    # Keep encrypted file if decryption fails
            
            # Update download record
            download['status'] = 'completed'
            download['end_time'] = time.time()
            download['local_path'] = local_path
            
            logger.info(f"Download completed: {file_path}")
            
        except Exception as e:
            download['status'] = 'failed'
            download['error'] = str(e)
            logger.error(f"Download failed: {str(e)}")
    
    def get_download_status(self, download_id):
        """Get the status of a download."""
        download = self.downloads.get(download_id)
        if not download:
            return False, f"Download ID {download_id} not found"
        
        return True, download
    
    def p2p_send_message(self, domain_name, message, timer=300):
        """Send a P2P message to a domain."""
        # Ensure domain is in DDNS
        if not self.ddns.has_domain(domain_name):
            return False, f"Domain {domain_name} not in DDNS"
        
        # Initiate or get PFS session
        session = self.pfs_sessions.get(domain_name)
        if not session or not session.get('established'):
            success, result = self.pfs_initiate(domain_name)
            if not success:
                return False, f"Failed to establish PFS session: {result}"
            session = result
        
        # Resolve domain
        success, result = self.resolve_domain(domain_name)
        if not success:
            return False, result
        
        ip, port = result
        
        try:
            # Encrypt message
            encrypted_message = self.security_manager.pfs_encrypt(session, message.encode())
            
            # Send message
            response = requests.post(
                f"http://{ip}:{port}/p2p/message",
                json={
                    'client_id': self.client_id,
                    'session_id': session['session_id'],
                    'encrypted_message': base64.b64encode(encrypted_message).decode(),
                    'timer': timer
                },
                timeout=10
            )
            
            if response.status_code == 200:
                data = response.json()
                if data.get('success'):
                    # Add to message history
                    if domain_name not in self.message_history:
                        self.message_history[domain_name] = []
                    
                    self.message_history[domain_name].append({
                        'sent': True,
                        'message': message,
                        'timestamp': time.time()
                    })
                    
                    logger.info(f"Message sent to {domain_name}")
                    return True, "Message sent"
                else:
                    logger.error(f"Failed to send message: {data.get('error', 'Unknown error')}")
                    return False, data.get('error', 'Unknown error')
            else:
                logger.error(f"Failed to send message: HTTP {response.status_code}")
                return False, f"HTTP Error: {response.status_code}"
            
        except requests.RequestException as e:
            logger.error(f"Network error sending message: {str(e)}")
            return False, f"Network error: {str(e)}"
    
    def get_message_history(self, domain_name):
        """Get message history for a domain."""
        if domain_name not in self.message_history:
            return []
        
        return self.message_history[domain_name]
    
    def process_command(self, command):
        """Process a command from the command line interface."""
        parts = command.strip().split()
        if not parts:
            return False, "Empty command"
        
        cmd = parts[0].lower()
        
        # Process /sources command
        if cmd == CMD_SOURCES:
            success, result = self.get_sources(force_refresh=True)
            if success:
                domains = result
                return True, {
                    'command': CMD_SOURCES,
                    'count': len(domains),
                    'domains': [d.to_dict() for d in domains.values()]
                }
            else:
                return False, result
        if cmd == CMD_HELP:
            help_text = {
                '/sources': "List all available domains",
                '/download': "Download a file from a domain. Usage: /download file_path domain_name [save_dir]",
                '/p2p': "Send a P2P message to a domain. Usage: /p2p domain_name timer message",
                '/visit': "Visit a domain. Usage: /visit domain_name [seconds]",
                '/help': "Show this help message"
            }
            return True, {
                'command': CMD_HELP,
                'help': help_text
            }
    
        # Process /visit command
        elif cmd == CMD_VISIT:
            if len(parts) < 2:
                return False, "Usage: /visit domain_name [seconds]"
            
            domain_name = parts[1]
            visit_seconds = 0
            if len(parts) >= 3:
                try:
                    visit_seconds = int(parts[2])
                except ValueError:
                    return False, "Seconds must be a number"
            
            return True, {
                'command': CMD_VISIT,
                'domain': domain_name,
                'seconds': visit_seconds
            }
        # Process /download command
        elif cmd == CMD_DOWNLOAD and len(parts) >= 3:
            file_path = parts[1]
            domain_name = parts[2]
            save_dir = parts[3] if len(parts) > 3 else os.path.expanduser("~/Downloads")
            
            success, result = self.download_file(domain_name, file_path, save_dir)
            if success:
                download_id = result
                return True, {
                    'command': CMD_DOWNLOAD,
                    'download_id': download_id,
                    'domain': domain_name,
                    'file': file_path
                }
            else:
                return False, result

        # Process /p2p command
        elif cmd == CMD_P2P and len(parts) >= 4:
            domain_name = parts[1]
            try:
                timer = int(parts[2])
            except ValueError:
                return False, "Timer must be a number"
            
            message = ' '.join(parts[3:])
            
            success, result = self.p2p_send_message(domain_name, message, timer)
            if success:
                return True, {
                    'command': CMD_P2P,
                    'domain': domain_name,
                    'timer': timer,
                    'message': message
                }
            else:
                return False, result
        
        else:
            return False, f"Unknown command: {command}"