<?php
namespace boru\ai\Asset;

use boru\ai\Config\Config;
use boru\ai\Config\ConfigResolver;

class AssetBindingPolicy
{
    /** @var array */
    protected $config = array();

    public function __construct(array $config = array())
    {
        $this->config = $this->normalize($config);
    }

    public static function fromConfig(Config $config = null, $providerName = null)
    {
        $providerName = $providerName ? (string)$providerName : 'default';
        $resolver = new ConfigResolver($config);

        $resolved = array(
            'reuse' => $resolver->resolveProviderSetting($providerName, 'asset_bindings.reuse', true, 'persistence'),
            'max_age_seconds' => $resolver->resolveProviderSetting($providerName, 'asset_bindings.max_age_seconds', null, 'persistence'),
            'delete_remote_on_cleanup' => $resolver->resolveProviderSetting($providerName, 'asset_bindings.delete_remote_on_cleanup', false, 'persistence'),
            'track_last_used_at' => $resolver->resolveProviderSetting($providerName, 'asset_bindings.track_last_used_at', true, 'persistence'),
        );

        return new self($resolved);
    }

    public function toArray()
    {
        return $this->config;
    }

    public function get($key, $default = null)
    {
        return isset($this->config[$key]) ? $this->config[$key] : $default;
    }

    public function reuse()
    {
        return (bool)$this->get('reuse', true);
    }

    public function maxAgeSeconds()
    {
        $value = $this->get('max_age_seconds', 0);
        return $value === null ? null : (int)$value;
    }

    public function deleteRemoteOnCleanup()
    {
        return (bool)$this->get('delete_remote_on_cleanup', false);
    }

    public function trackLastUsedAt()
    {
        return (bool)$this->get('track_last_used_at', true);
    }

    public function shouldReuse(ProviderAssetBinding $binding)
    {
        if (!$this->reuse()) {
            return false;
        }

        $maxAgeSeconds = $this->maxAgeSeconds();
        if ($maxAgeSeconds === null || $maxAgeSeconds <= 0) {
            return true;
        }

        $referenceTime = $binding->metadata('last_used_at');
        if (!$referenceTime) {
            $referenceTime = $binding->updatedAt() ? $binding->updatedAt() : $binding->createdAt();
        }
        if (!$referenceTime) {
            return true;
        }

        $timestamp = strtotime($referenceTime);
        if ($timestamp === false) {
            return true;
        }

        return (time() - $timestamp) <= $maxAgeSeconds;
    }

    protected function normalize(array $config)
    {
        $defaults = array(
            'reuse' => true,
            'max_age_seconds' => null,
            'delete_remote_on_cleanup' => false,
            'track_last_used_at' => true,
        );

        foreach ($config as $key => $value) {
            $defaults[$key] = $value;
        }

        return $defaults;
    }
}
