<?php

declare(strict_types=1);

namespace Archive\Archived;

final class CacheabilityInfo
{
    public bool $hasDynamicComponents = false;
    public bool $hasUserSpecificContent = false;
    public bool $hasFormElements = false;
    public bool $hasTimeBasedContent = false;
    public bool $hasSessionData = false;
    public array $staticFragments = [];
    public array $dynamicFragments = [];
    public array $dynamicComponents = [];
    public CacheStrategy $cacheStrategy = CacheStrategy::DYNAMIC;
    public int $ttl = 0;
    public array $dependencies = [];

    public function isFullyCacheable(): bool
    {
        return !$this->hasDynamicComponents
            && !$this->hasUserSpecificContent
            && !$this->hasFormElements
            && !$this->hasSessionData
            && !$this->hasTimeBasedContent;
    }

    public function isPartiallyCacheable(): bool
    {
        return count($this->staticFragments) > 0 && !$this->hasUserSpecificContent;
    }

    public function shouldUseFragmentCache(): bool
    {
        return count($this->staticFragments) > 0 || count($this->dynamicFragments) > 0;
    }

    public function getCacheComplexity(): int
    {
        $complexity = 0;
        $complexity += count($this->staticFragments);
        $complexity += count($this->dynamicFragments) * 3;
        $complexity += $this->hasUserSpecificContent ? 5 : 0;
        $complexity += $this->hasFormElements ? 3 : 0;
        $complexity += $this->hasDynamicComponents ? 4 : 0;

        return $complexity;
    }

    public function addStaticFragment(string $fragmentId): void
    {
        if (!in_array($fragmentId, $this->staticFragments, true)) {
            $this->staticFragments[] = $fragmentId;
        }
    }

    public function addDynamicFragment(string $fragmentId): void
    {
        if (!in_array($fragmentId, $this->dynamicFragments, true)) {
            $this->dynamicFragments[] = $fragmentId;
        }
    }

    public function hasFragments(): bool
    {
        return count($this->staticFragments) > 0 || count($this->dynamicFragments) > 0;
    }

    public function getFragmentCount(): int
    {
        return count($this->staticFragments) + count($this->dynamicFragments);
    }
}
