"""Configuration and secure token storage."""

from cryptography.fernet import Fernet
import json
from pathlib import Path
import fcntl
import time

CONFIG_DIR = Path.home() / '.mcpbundles'
TOKEN_FILE = CONFIG_DIR / 'token.json'
KEY_FILE = CONFIG_DIR / '.key'
STATUS_FILE = CONFIG_DIR / 'status.json'


def get_or_create_key():
    """Get or create encryption key for token storage."""
    CONFIG_DIR.mkdir(exist_ok=True)
    if not KEY_FILE.exists():
        key = Fernet.generate_key()
        KEY_FILE.write_bytes(key)
        KEY_FILE.chmod(0o600)  # Secure file permissions
    return KEY_FILE.read_bytes()


def save_token(token_data):
    """Save token data encrypted to disk."""
    CONFIG_DIR.mkdir(exist_ok=True)
    key = get_or_create_key()
    cipher = Fernet(key)
    encrypted = cipher.encrypt(json.dumps(token_data).encode())
    
    # Use file locking for concurrent access
    lock_file = CONFIG_DIR / '.token.lock'
    max_retries = 5
    for attempt in range(max_retries):
        try:
            with open(lock_file, 'w') as lock:
                fcntl.flock(lock.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
                try:
                    TOKEN_FILE.write_bytes(encrypted)
                    TOKEN_FILE.chmod(0o600)  # Secure file permissions
                finally:
                    fcntl.flock(lock.fileno(), fcntl.LOCK_UN)
            break
        except (IOError, OSError):
            if attempt < max_retries - 1:
                time.sleep(0.1 * (attempt + 1))  # Exponential backoff
            else:
                # Last attempt, just write without lock
                TOKEN_FILE.write_bytes(encrypted)
                TOKEN_FILE.chmod(0o600)


def load_token():
    """Load token data from disk."""
    if not TOKEN_FILE.exists():
        return None
    
    # Use file locking for concurrent access
    lock_file = CONFIG_DIR / '.token.lock'
    max_retries = 5
    for attempt in range(max_retries):
        try:
            with open(lock_file, 'w') as lock:
                fcntl.flock(lock.fileno(), fcntl.LOCK_SH | fcntl.LOCK_NB)
                try:
                    key = get_or_create_key()
                    cipher = Fernet(key)
                    decrypted = cipher.decrypt(TOKEN_FILE.read_bytes())
                    return json.loads(decrypted)
                finally:
                    fcntl.flock(lock.fileno(), fcntl.LOCK_UN)
        except (IOError, OSError):
            if attempt < max_retries - 1:
                time.sleep(0.1 * (attempt + 1))  # Exponential backoff
            else:
                # Last attempt, just read without lock
                try:
                    key = get_or_create_key()
                    cipher = Fernet(key)
                    decrypted = cipher.decrypt(TOKEN_FILE.read_bytes())
                    return json.loads(decrypted)
                except Exception:
                    return None
        except Exception:
            return None
    return None


def save_status(status_data):
    """Save daemon status for status command."""
    CONFIG_DIR.mkdir(exist_ok=True)
    with open(STATUS_FILE, 'w') as f:
        json.dump(status_data, f)


def delete_token():
    """Delete stored token."""
    TOKEN_FILE.unlink(missing_ok=True)

