"""Base cloud provider interface."""

from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Optional, List
from pathlib import Path


@dataclass
class CloudFile:
    """Represents a file in cloud storage."""
    id: str
    name: str
    path: str
    size: int
    mime_type: str
    url: Optional[str] = None
    web_link: Optional[str] = None


class CloudProvider(ABC):
    """Abstract base class for cloud storage providers."""

    @property
    @abstractmethod
    def name(self) -> str:
        """Provider name (e.g., 'google_drive', 'dropbox')."""
        pass  # pragma: no cover

    @property
    @abstractmethod
    def display_name(self) -> str:
        """Human-readable provider name."""
        pass  # pragma: no cover

    @abstractmethod
    def is_authenticated(self) -> bool:
        """Check if the provider is authenticated."""
        pass  # pragma: no cover

    @abstractmethod
    async def authenticate(self, credentials: dict) -> bool:
        """
        Authenticate with the cloud provider.

        Args:
            credentials: Provider-specific credentials

        Returns:
            True if authentication successful
        """
        pass  # pragma: no cover

    @abstractmethod
    async def upload_file(
        self,
        file_path: str,
        cloud_path: str = None,
        content_type: str = None
    ) -> CloudFile:
        """
        Upload a file to cloud storage.

        Args:
            file_path: Local path to the file
            cloud_path: Destination path in cloud storage
            content_type: MIME type of the file

        Returns:
            CloudFile with upload details
        """
        pass  # pragma: no cover

    @abstractmethod
    async def upload_content(
        self,
        content: bytes,
        filename: str,
        cloud_path: str = None,
        content_type: str = None
    ) -> CloudFile:
        """
        Upload content directly to cloud storage.

        Args:
            content: File content as bytes
            filename: Name for the file
            cloud_path: Destination path in cloud storage
            content_type: MIME type of the content

        Returns:
            CloudFile with upload details
        """
        pass  # pragma: no cover

    @abstractmethod
    async def list_files(self, folder_path: str = None) -> List[CloudFile]:
        """
        List files in cloud storage.

        Args:
            folder_path: Optional folder path to list

        Returns:
            List of CloudFile objects
        """
        pass  # pragma: no cover

    @abstractmethod
    async def delete_file(self, file_id: str) -> bool:
        """
        Delete a file from cloud storage.

        Args:
            file_id: ID of the file to delete

        Returns:
            True if deletion successful
        """
        pass  # pragma: no cover

    @abstractmethod
    async def get_share_link(self, file_id: str) -> str:
        """
        Get a shareable link for a file.

        Args:
            file_id: ID of the file

        Returns:
            Shareable URL
        """
        pass  # pragma: no cover


def get_content_type(filename: str) -> str:
    """Get MIME type based on file extension."""
    ext = Path(filename).suffix.lower()
    content_types = {
        '.txt': 'text/plain',
        '.md': 'text/markdown',
        '.pdf': 'application/pdf',
        '.srt': 'text/plain',
        '.vtt': 'text/vtt',
        '.json': 'application/json',
    }
    return content_types.get(ext, 'application/octet-stream')
