#!/usr/bin/env python3
import os
import subprocess
import shutil
import time
from pathlib import Path
from urllib.parse import quote
from dataclasses import dataclass
from typing import Optional


@dataclass
class SMBConfig:
    """Configuration for an SMB mount."""
    server: str
    share: str
    username: str
    password: str
    mount_name: str  # Name for the mount folder (e.g., "GDriveNetwork")
    local_dest: Optional[str] = None  # Optional local destination for syncing
    
    @property
    def mount_point(self) -> str:
        """Returns the full mount point path."""
        return str(Path.home() / "NetworkMounts" / self.mount_name)


def is_mounted(mount_point: str) -> bool:
    """Check if a path is currently mounted."""
    return os.path.ismount(mount_point)


def mount_share(config: SMBConfig) -> bool:
    """
    Mount an SMB share using the provided configuration.
    Returns True if successful, False otherwise.
    """
    mount_point = config.mount_point
    
    # Create mount point directory if it doesn't exist
    Path(mount_point).mkdir(parents=True, exist_ok=True)
    
    # Build the SMB URL
    # Format: //username:password@server/share
    if config.username and config.password:
        escaped_pass = quote(config.password, safe='')
        smb_url = f"//{config.username}:{escaped_pass}@{config.server}/{config.share}"
    else:
        smb_url = f"//{config.server}/{config.share}"
    
    # Mount command for macOS
    cmd = ["mount_smbfs", smb_url, mount_point]
    
    try:
        print(f"Mounting {config.share} from {config.server}...")
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"Successfully mounted to {mount_point}")
        return True
    except subprocess.CalledProcessError as e:
        print(f"Failed to mount: {e.stderr}")
        return False


def unmount_share(config: SMBConfig) -> bool:
    """Unmount an SMB share."""
    mount_point = config.mount_point
    
    if not is_mounted(mount_point):
        print(f"{mount_point} is not mounted.")
        return True
    
    try:
        subprocess.run(["umount", mount_point], check=True, capture_output=True, text=True)
        print(f"Successfully unmounted {mount_point}")
        return True
    except subprocess.CalledProcessError as e:
        print(f"Failed to unmount: {e.stderr}")
        return False


def ensure_mounted(config: SMBConfig) -> bool:
    """
    Ensure a share is mounted. Mount it if not already mounted.
    Returns True if mounted (or already was), False if mount failed.
    """
    mount_point = config.mount_point
    
    if is_mounted(mount_point):
        print(f"{config.share} is already mounted at {mount_point}")
        return True
    
    print(f"{config.share} not mounted. Attempting to mount...")
    return mount_share(config)


# -----------------------------
# PREDEFINED CONFIGURATIONS
# -----------------------------
# Add your different mount configurations here

CONFIGS = {
    "gdrive": SMBConfig(
        server="192.168.1.68",
        share="GDrive",
        username="macos",
        password="dromischSYNC123987me",
        mount_name="GDrive",
        local_dest="/Users/dromisch/NetworkMounts/GDrive"
    ),
    
    # Example: Add more configurations as needed
    # "photos": SMBConfig(
    #     server="192.168.1.68",
    #     share="Photos",
    #     username="photouser",
    #     password="photopass",
    #     mount_name="PhotosNetwork",
    #     local_dest="/Volumes/ExtraDrive/Photos"
    # ),
    
    # "backup": SMBConfig(
    #     server="192.168.1.100",
    #     share="Backups",
    #     username="backupuser",
    #     password="backuppass",
    #     mount_name="BackupNetwork"
    # ),
}


def list_configs():
    """Print available configurations."""
    print("Available mount configurations:")
    for name, config in CONFIGS.items():
        status = "mounted" if is_mounted(config.mount_point) else "not mounted"
        print(f"  {name}: //{config.server}/{config.share} ({status})")


def main():
    import argparse
    
    parser = argparse.ArgumentParser(description="Mount SMB network shares")
    parser.add_argument("config", nargs="?", help="Configuration name to mount")
    parser.add_argument("-l", "--list", action="store_true", help="List available configurations")
    parser.add_argument("-u", "--unmount", action="store_true", help="Unmount instead of mount")
    parser.add_argument("-a", "--all", action="store_true", help="Mount/unmount all configurations")
    
    args = parser.parse_args()
    
    if args.list:
        list_configs()
        return
    
    if args.all:
        for name, config in CONFIGS.items():
            print(f"\n--- {name} ---")
            if args.unmount:
                unmount_share(config)
            else:
                ensure_mounted(config)
        return
    
    if not args.config:
        parser.print_help()
        print("\n")
        list_configs()
        return
    
    if args.config not in CONFIGS:
        print(f"Unknown configuration: {args.config}")
        list_configs()
        return
    
    config = CONFIGS[args.config]
    
    if args.unmount:
        unmount_share(config)
    else:
        ensure_mounted(config)


if __name__ == "__main__":
    main()