from datetime import datetime
from typing import Any, Dict, List, Optional, Union
from enum import Enum


class Function:
    def __init__(self, id: str, name: str, language: str, platform: str) -> None:
        self.id: str = id
        self.name: str = name
        self.language: str = language
        self.platform: str = platform


class Version:
    def __init__(
        self, function: Function, version_number: str, origin: str, code: str, created_at: datetime
    ) -> None:
        self.function: Function = function
        self.version_number: str = version_number
        self.origin: str = origin
        self.code: str = code
        self.created_at: datetime = created_at


class OptimizationReport:
    def __init__(
        self,
        version: Version,
        report_id: str,
        recommendations: List[str],
        optimized_code: str,
        metrics_before: Dict[str, Any],
        metrics_after: Dict[str, Any],
        created_at: datetime,
    ) -> None:
        self.version: Version = version
        self.report_id: str = report_id
        self.recommendations: List[str] = recommendations
        self.optimized_code: str = optimized_code
        self.metrics_before: Dict[str, Any] = metrics_before
        self.metrics_after: Dict[str, Any] = metrics_after
        self.created_at: datetime = created_at


class TestConfiguration:
    def __init__(
        self, version: Version, runtime: str, iterations: int, parallelism: int, timeout: int
    ) -> None:
        self.version: Version = version
        self.runtime: str = runtime
        self.iterations: int = iterations
        self.parallelism: int = parallelism
        self.timeout: int = timeout


class TestRunStatus(Enum):
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"


class TestRun:
    def __init__(
        self,
        test_configuration: TestConfiguration,
        run_id: str,
        started_at: datetime,
        ended_at: Optional[datetime] = None,
        status: TestRunStatus = TestRunStatus.PENDING,
    ) -> None:
        self.test_configuration: TestConfiguration = test_configuration
        self.run_id: str = run_id
        self.started_at: datetime = started_at
        self.ended_at: Optional[datetime] = ended_at
        self.status: TestRunStatus = status


class Metric:
    def __init__(
        self, test_run: TestRun, type: str, percentiles: Dict[str, float], timestamp: datetime
    ) -> None:
        self.test_run: TestRun = test_run
        self.type: str = type
        self.percentiles: Dict[str, float] = percentiles
        self.timestamp: datetime = timestamp


class TestProfile:
    def __init__(
        self,
        test_run: TestRun,
        profile_id: str,
        function_name: str,
        version_number: str,
        run_timestamp: datetime,
    ) -> None:
        self.test_run: TestRun = test_run
        self.profile_id: str = profile_id
        self.function_name: str = function_name
        self.version_number: str = version_number
        self.run_timestamp: datetime = run_timestamp


class Draft:
    def __init__(self, version: Version, content: str, last_updated: datetime) -> None:
        self.version: Version = version
        self.content: str = content
        self.last_updated: datetime = last_updated 