<?php

declare(strict_types=1);

namespace App\Framework\Queue\Contracts;

use App\Framework\Queue\Entities\JobDependencyEntry;
use App\Framework\Queue\ValueObjects\JobDependency;

/**
 * Interface for managing job dependencies
 */
interface JobDependencyManagerInterface
{
    /**
     * Add a dependency between two jobs
     */
    public function addDependency(JobDependency $dependency): void;

    /**
     * Remove a dependency
     */
    public function removeDependency(string $dependentJobId, string $dependsOnJobId): void;

    /**
     * Get all dependencies for a job (jobs this job depends on)
     */
    public function getDependencies(string $jobId): array;

    /**
     * Get all dependents for a job (jobs that depend on this job)
     */
    public function getDependents(string $jobId): array;

    /**
     * Check if a job has any unsatisfied dependencies
     */
    public function hasUnsatisfiedDependencies(string $jobId): bool;

    /**
     * Get unsatisfied dependencies for a job
     *
     * @return JobDependencyEntry[]
     */
    public function getUnsatisfiedDependencies(string $jobId): array;

    /**
     * Mark a dependency as satisfied
     */
    public function markDependencyAsSatisfied(string $dependentJobId, string $dependsOnJobId): void;

    /**
     * Check if a job can be executed (all dependencies satisfied)
     */
    public function canJobBeExecuted(string $jobId): bool;

    /**
     * Get jobs that are ready to be executed (no unsatisfied dependencies)
     */
    public function getReadyJobs(): array;

    /**
     * Resolve dependencies when a job completes
     */
    public function resolveJobCompletion(string $jobId, bool $successful = true): array;

    /**
     * Get dependency chain for a job (all jobs it transitively depends on)
     */
    public function getDependencyChain(string $jobId): array;

    /**
     * Check for circular dependencies
     */
    public function hasCircularDependencies(string $jobId): bool;

    /**
     * Clean up old satisfied dependencies
     */
    public function cleanupOldDependencies(int $olderThanDays = 30): int;
}
