<?php

namespace Dipper\Foundation\Repository;

use Illuminate\Cache\TaggableStore;
use Illuminate\Contracts\Cache\Repository as CacheRepository;

/**
 * Class CacheKeys.
 */
class CacheKeys
{
    const CACHE_KEY = 'repository-cache-keys';

    /**
     * @var array
     */
    protected $keys = null;

    /**
     * @param $group
     * @param $key
     *
     * @return void
     */
    public function putKey($group, $key)
    {
        $this->loadKeys();

        $this->$keys[$group] = $this->getKeys($group);

        if (!in_array($key, $this->$keys[$group])) {
            $this->$keys[$group][] = $key;
        }

        $this->storeKeys();
    }

    /**
     * @return array|mixed
     */
    public function loadKeys()
    {
        if (!is_null($this->$keys) && is_array($this->$keys)) {
            return $this->$keys;
        }

        $content = $this->getCacheRepository()->get(self::CACHE_KEY);
        $this->$keys = json_decode($content, true);

        return $this->$keys;
    }

    /**
     * @return int
     */
    public function storeKeys()
    {
        $this->$keys = is_null($this->$keys) ? [] : $this->$keys;
        $content = json_encode($this->$keys);

        $this->getCacheRepository()->forever(self::CACHE_KEY, $content);
    }

    /**
     * @param $group
     *
     * @return array|mixed
     */
    public function getKeys($group)
    {
        $this->loadKeys();
        $this->$keys[$group] = isset($this->$keys[$group]) ? $this->$keys[$group] : [];

        return $this->$keys[$group];
    }

    /**
     * Set Cache Repository.
     *
     * @param CacheRepository $repository
     *
     * @return $this
     */
    public function setCacheRepository(CacheRepository $repository)
    {
        $this->cacheRepository = $repository;

        return $this;
    }

    /**
     * Return instance of Cache Repository.
     *
     * @return CacheRepository
     */
    public function getCacheRepository()
    {
        if (is_null($this->cacheRepository)) {
            $this->cacheRepository = app(config('dipper.repository.cache.repository', 'cache'));
        }

        return $this->cacheRepository;
    }

    /**
     * 判断是否可以使用Tag
     *
     * @param CacheRepository $repository
     * @return boolean
     */
    public static function isTaggable($repository)
    {
        return $repository->getStore() instanceof TaggableStore;
    }
}
