<?php
namespace boru\ai\Embedding;

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

class EmbeddingCachePolicy
{
    /** @var bool */
    protected $enabled = true;

    /** @var bool */
    protected $read = true;

    /** @var bool */
    protected $write = true;

    /** @var int|null */
    protected $ttlSeconds;

    /** @var string|null */
    protected $namespace;

    public static function fromConfig(Config $config = null, $provider = null, EmbeddingRequest $request = null)
    {
        $resolver = new ConfigResolver($config);
        $provider = (string)$provider;

        $policy = new self();
        $policy->enabled($resolver->resolveProviderSetting($provider, 'cache.enabled', true, 'vector'));
        $policy->read($resolver->resolveProviderSetting($provider, 'cache.read', true, 'vector'));
        $policy->write($resolver->resolveProviderSetting($provider, 'cache.write', true, 'vector'));
        $ttl = $resolver->resolveProviderSetting($provider, 'cache.ttl_seconds', null, 'vector');
        $policy->ttlSeconds($ttl === null || $ttl === '' ? null : (int)$ttl);
        $namespace = $resolver->resolveProviderSetting($provider, 'cache.namespace', null, 'vector');
        if ($namespace !== null && $namespace !== '') {
            $policy->namespace((string)$namespace);
        }

        if ($request instanceof EmbeddingRequest) {
            $cache = $request->option('cache');
            if ($cache !== null) {
                $policy->enabled($cache ? true : false);
            }

            $cacheRead = $request->option('cache_read');
            if ($cacheRead !== null) {
                $policy->read($cacheRead ? true : false);
            }

            $cacheWrite = $request->option('cache_write');
            if ($cacheWrite !== null) {
                $policy->write($cacheWrite ? true : false);
            }

            $cacheTtl = $request->option('cache_ttl_seconds');
            if ($cacheTtl !== null && $cacheTtl !== '') {
                $policy->ttlSeconds((int)$cacheTtl);
            }

            $cacheNamespace = $request->option('cache_namespace');
            if ($cacheNamespace !== null && $cacheNamespace !== '') {
                $policy->namespace((string)$cacheNamespace);
            }
        }

        return $policy;
    }

    public function enabled($value = null)
    {
        if ($value !== null) {
            $this->enabled = $value ? true : false;
            return $this;
        }
        return $this->enabled ? true : false;
    }

    public function read($value = null)
    {
        if ($value !== null) {
            $this->read = $value ? true : false;
            return $this;
        }
        return $this->read ? true : false;
    }

    public function write($value = null)
    {
        if ($value !== null) {
            $this->write = $value ? true : false;
            return $this;
        }
        return $this->write ? true : false;
    }

    public function ttlSeconds($value = null)
    {
        if (func_num_args() > 0) {
            $this->ttlSeconds = $value === null ? null : (int)$value;
            return $this;
        }
        return $this->ttlSeconds;
    }

    public function namespace($value = null)
    {
        if ($value !== null) {
            $this->namespace = (string)$value;
            return $this;
        }
        return $this->namespace;
    }

    public function canRead()
    {
        return $this->enabled() && $this->read();
    }

    public function canWrite()
    {
        return $this->enabled() && $this->write();
    }
}
