"""
Utility functions shared across components.
"""
import os
import json
import logging
import platform
import random
import string
import socket
import ipaddress
from pathlib import Path
from datetime import datetime, timedelta

def setup_logging(name, level=logging.INFO):
    """Setup logging with a consistent format."""
    logger = logging.getLogger(name)
    logger.setLevel(level)
    
    if not logger.handlers:
        handler = logging.StreamHandler()
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
        logger.addHandler(handler)
    
    return logger

def generate_random_string(length=16):
    """Generate a random string of fixed length."""
    characters = string.ascii_letters + string.digits
    return ''.join(random.choice(characters) for _ in range(length))

def ensure_directory_exists(path):
    """Ensure that a directory exists, creating it if necessary."""
    os.makedirs(path, exist_ok=True)
    return path

def get_data_dir():
    """Get the appropriate data directory for the platform."""
    home = Path.home()
    
    if platform.system() == "Windows":
        return home / "AppData" / "Local" / "DecentraBrowser"
    elif platform.system() == "Darwin":
        return home / "Library" / "Application Support" / "DecentraBrowser"
    else:
        return home / ".decentrabrowser"

def load_json_file(file_path, default=None):
    """Load JSON from a file, returning default if the file doesn't exist."""
    if default is None:
        default = {}
    
    try:
        with open(file_path, 'r') as f:
            return json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        return default

def save_json_file(file_path, data):
    """Save data as JSON to a file."""
    directory = os.path.dirname(file_path)
    if directory:
        os.makedirs(directory, exist_ok=True)
        
    with open(file_path, 'w') as f:
        json.dump(data, f, indent=2)

def get_local_ip():
    """Get the local IP address."""
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # Doesn't need to be reachable
        s.connect(('10.255.255.255', 1))
        ip = s.getsockname()[0]
    except Exception:
        ip = '127.0.0.1'
    finally:
        s.close()
    return ip

def is_valid_domain_format(domain):
    """Check if a domain follows the prefix.main.suffix.domain format."""
    parts = domain.split('.')
    if len(parts) != 4 or parts[3] != 'domain':
        return False
    return all(part for part in parts)  # Ensure no empty parts

def is_valid_ipv4(ip):
    """Check if a string is a valid IPv4 address."""
    try:
        ipaddress.IPv4Address(ip)
        return True
    except ValueError:
        return False