<?php
/**
 * Prohibit direct script loading
 */
defined('ABSPATH') || die('No direct script access allowed!');

/**
 * Class handling the redirect options
 */
class WpmsRedirectOption
{
    /**
     * Redirects list
     *
     * @var array|mixed|void
     */
    private $redirects = array();

    /**
     * WpmsRedirectOption constructor.
     *
     * @param boolean $redirects Is redirects
     */
    public function __construct($redirects = true)
    {
        if ($redirects) {
            $this->redirects = $this->getAll();
        }
    }

    /**
     * Get all the redirect
     *
     * @return array|mixed
     */
    public function getAll()
    {
        $redirects = $this->getFromOption();

        array_walk($redirects, array($this, 'mapOptionToObject'));

        return $redirects;
    }

    /**
     * Add redirect url to array
     *
     * @param WpmsRedirect $redirect WpmsRedirect class
     *
     * @return boolean
     */
    public function add(WpmsRedirect $redirect)
    {
        if ($this->search($redirect->getOrigin()) === false) {
            $this->redirects[] = $redirect;

            return true;
        }

        return false;
    }

    /**
     * Update
     *
     * @param WpmsRedirect $current_redirect Current redirect
     * @param WpmsRedirect $redirect         New redirect
     *
     * @return boolean
     */
    public function update(WpmsRedirect $current_redirect, WpmsRedirect $redirect)
    {
        $found = $this->search($current_redirect->getOrigin());
        if ($found !== false) {
            $this->redirects[$found] = $redirect;

            return true;
        }

        return false;
    }

    /**
     * Delete redirect
     *
     * @param WpmsRedirect $current_redirect Current redirect
     *
     * @return boolean
     */
    public function delete(WpmsRedirect $current_redirect)
    {
        $found = $this->search($current_redirect->getOrigin());
        if ($found !== false) {
            unset($this->redirects[$found]);

            return true;
        }

        return false;
    }

    /**
     * Get redirect
     *
     * @param string $origin URL
     *
     * @return boolean|mixed
     */
    public function get($origin)
    {
        $found = $this->search($origin);
        if ($found !== false) {
            return $this->redirects[$found];
        }

        return false;
    }

    /**
     * Search key
     *
     * @param string $origin URL
     *
     * @return boolean|integer|string
     */
    public function search($origin)
    {
        foreach ($this->redirects as $redirect_key => $redirect) {
            if ($redirect->originIs($origin)) {
                return $redirect_key;
            }
        }

        return false;
    }

    /**
     * Saving the redirects
     *
     * @param boolean $retry_upgrade Is retry upgrade
     *
     * @return void
     */
    public function save($retry_upgrade = true)
    {
        $redirects = $this->redirects;
        array_walk($redirects, array($this, 'mapObjectToOption'));
        // Update option
        update_option(WPMS_OPTION, apply_filters('wpms_addon_save_redirects', $redirects), false);
    }

    /**
     * Setting the redirects property
     *
     * @param string $option_name Option redirects name
     *
     * @return array|mixed
     */
    public function getFromOption($option_name = WPMS_OPTION)
    {
        $redirects = apply_filters('wpms_addon_get_redirects', get_option($option_name));
        if (!is_array($redirects)) {
            $redirects = array();
        }

        return $redirects;
    }

    /**
     * Maps array values to a redirect object.
     *
     * @param array $redirect_values Redirect values
     *
     * @return void
     */
    private function mapOptionToObject(array &$redirect_values)
    {
        $redirect_values = new WpmsRedirect(
            $redirect_values['origin'],
            $redirect_values['url'],
            $redirect_values['type'],
            $redirect_values['format']
        );
    }

    /**
     * Maps redirect object to an array option.
     *
     * @param WpmsRedirect $redirect WpmsRedirect class
     *
     * @return void
     */
    private function mapObjectToOption(WpmsRedirect &$redirect)
    {
        $redirect = array(
            'origin' => $redirect->getOrigin(),
            'url'    => $redirect->getTarget(),
            'type'   => $redirect->getType(),
            'format' => $redirect->getFormat()
        );
    }
}
