<?php namespace Tussendoor\Reloadify\Http\Filters;

use Tussendoor\Reloadify\Exceptions\FilterException;
use Tussendoor\Reloadify\Plugin;
use WP_REST_Request;

/**
 * This class is NOT extending the Filter class because this will not use the
 * builder and is only used to return keys from the plugin data array that are
 * requested via the filters parameter.
 */
class InfoFilter
{
    /**
     * The request instance.
     *
     * @var \WP_REST_Request
     */
    protected $request;

    /**
     * The plugin data.
     *
     * @var array
     */
    protected $info;

    /**
     * The accepted product info operators
     *
     * @var array
     */
    protected $acceptedOperators = [
        'in',
    ];

    public function __construct(WP_REST_Request $request)
    {
        $this->request = $request;
        $this->info = $this->getPluginInfo();
    }

    /**
     * Get the plugin info and convert the keys to snake_case
     *
     * @return array
     */
    public function getPluginInfo()
    {
        $data = get_plugin_data(Plugin::config('plugin.basepath'), false, false);

        return array_combine(
            array_map(function($key) {
                return str_replace(' ', '_', strtolower($key));
            }, array_keys($data)),
            array_values($data)
        );
    }

    /**
     * Apply the filters on the data
     *
     * @return array
     */
    public function apply()
    {
        if ($this->request->has_param('filters')) {
            foreach ($this->request->get_param('filters') as $attribute => $data) {
                if (method_exists($this, $attribute)) {
                    call_user_func_array([$this, $attribute], array_filter([$data]));
                }
            }
        }

        return $this->info;
    }

    /**
     * Filter the plugin info by the given keys
     *
     * @param array $filter
     * @return void
     */
    public function info($filter)
    {
        if (! array_key_exists('in', $filter)) {
            throw new FilterException('Accepted operators for info filter not found. Accepted types: ' . implode(', ', $this->acceptedOperators), 400);
        }
        if (! is_array($filter['in'])) {
            throw new FilterException('Unaccepted data type encountered for filter. Only accepted is "array". Given filter data: "' . $filter['in'] . '"', 400);
        }

        /**
         * Search for entries in the plugin data with the given keys
         * @example filters[info][in][]=version&filters[info][in][]=author
         */
        foreach ($filter['in'] as $key) {
            if (array_key_exists($key, $this->info)) {
                $data[$key] = $this->info[$key];
            }
        }

        $this->info = $data;
    }

}
