<?php

declare(strict_types=1);

namespace App\Framework\MachineLearning\ModelManagement;

use App\Framework\MachineLearning\ModelManagement\ValueObjects\ModelMetadata;
use App\Framework\MachineLearning\ModelManagement\ValueObjects\ModelType;
use App\Framework\Core\ValueObjects\Version;

/**
 * Model Registry - Centralized ML Model Management
 *
 * Provides CRUD operations for ML model metadata:
 * - Register new models
 * - Retrieve model metadata
 * - Update model configuration and metrics
 * - List models by type/environment
 * - Version management
 *
 * Storage:
 * - CacheModelRegistry: Cache-based storage (production)
 * - InMemoryModelRegistry: In-memory storage (testing)
 *
 * Usage:
 * ```php
 * // Register model
 * $metadata = ModelMetadata::forN1Detector(Version::fromString('1.0.0'));
 * $registry->register($metadata);
 *
 * // Retrieve model
 * $model = $registry->get('n1-detector', Version::fromString('1.0.0'));
 *
 * // Get latest version
 * $latest = $registry->getLatest('n1-detector');
 * ```
 */
interface ModelRegistry
{
    /**
     * Register a new model
     *
     * @throws ModelAlreadyExistsException if model with same name and version exists
     */
    public function register(ModelMetadata $metadata): void;

    /**
     * Get model by name and version
     *
     * @return ModelMetadata|null Returns null if model not found
     */
    public function get(string $modelName, Version $version): ?ModelMetadata;

    /**
     * Get latest version of model by name
     *
     * @return ModelMetadata|null Returns null if no models found for this name
     */
    public function getLatest(string $modelName): ?ModelMetadata;

    /**
     * Get all versions of a model
     *
     * @return array<ModelMetadata> Sorted by version (newest first)
     */
    public function getAll(string $modelName): array;

    /**
     * Get models by type
     *
     * @return array<ModelMetadata>
     */
    public function getByType(ModelType $type): array;

    /**
     * Get models deployed to environment
     *
     * @return array<ModelMetadata>
     */
    public function getByEnvironment(string $environment): array;

    /**
     * Get all production models
     *
     * @return array<ModelMetadata>
     */
    public function getProductionModels(): array;

    /**
     * Update model metadata (configuration, performance metrics, etc.)
     *
     * @throws ModelNotFoundException if model not found
     */
    public function update(ModelMetadata $metadata): void;

    /**
     * Delete model
     *
     * @return bool Returns true if deleted, false if not found
     */
    public function delete(string $modelName, Version $version): bool;

    /**
     * Check if model exists
     */
    public function exists(string $modelName, Version $version): bool;

    /**
     * Get all registered model names
     *
     * @return array<string>
     */
    public function getAllModelNames(): array;

    /**
     * Get version count for a model
     */
    public function getVersionCount(string $modelName): int;

    /**
     * Get total model count across all names and versions
     */
    public function getTotalCount(): int;

    /**
     * Clear all models (use with caution)
     */
    public function clear(): void;
}
