<?php

/**
 * Handles the parameters and url
 *
 * @author StarBox
 */
class CTLPPU_Classes_Tools extends CTLPPU_Classes_FrontController {

    /** @var array Saved options in database */
    public static $options = array();
    public static $debug = array();

    /** @var integer Count the errors in site */
    static $errors_count = 0;

    public function __construct() {
        parent::__construct();

        self::$options = $this->getOptions();
        $this->checkDebug(); //dev mode
    }

    /**
     * Load the Options from user option table in DB
     *
     * @return array
     */
    public static function getOptions() {
        $init = array(
            'ctlppu_ver' => CTLPPU_VERSION,
            'synced' => null,
            'blog_id' => null,
            'token' => null,
            'last_update' => 0
        );

        if (is_multisite()) {
            $options = json_decode(get_blog_option(get_current_blog_id(), _CTLPPU_OPTION_), true);
        } else {
            $options = json_decode(get_option(_CTLPPU_OPTION_), true);
        }

        if (isset($options) && !empty($options)) {
            $options = @array_merge($init, $options);
        } else {
            return $init;
        }

        return $options;
    }

    /**
     * Check if debug is called
     */
    private function checkDebug() {
        //if debug is called
        if (self::getIsset('ctlppu_debug')) {
            if (self::getValue('ctlppu_debug') === 'on') {
                if (function_exists('register_shutdown_function')) {
                    register_shutdown_function(array($this, 'showDebug'));
                }
            }
        }
    }

    /**
     * Check if ajax
     * @return bool
     */
    public static function isAjax() {
        return (defined('DOING_AJAX') && DOING_AJAX);
    }

    /**
     * Store the debug for a later view
     */
    public static function dump() {
        if (self::getValue('ctlppu_debug') !== 'on') {
            return;
        }

        $output = '';
        $callee = array('file' => '', 'line' => '');
        if (function_exists('func_get_args')) {
            $arguments = func_get_args();
            $total_arguments = count($arguments);
        } else
            $arguments = array();


        $run_time = number_format(microtime(true) - CTLPPU_REQUEST_TIME, 3);
        if (function_exists('debug_backtrace'))
            list($callee) = debug_backtrace();

        $output .= '<fieldset style="background: #FFFFFF; border: 1px #CCCCCC solid; padding: 5px; font-size: 9pt; margin: 0;">';
        $output .= '<legend style="background: #EEEEEE; padding: 2px; font-size: 8pt;">' . $callee['file'] . ' Time: ' . $run_time . ' @ line: ' . $callee['line']
            . '</legend><pre style="margin: 0; font-size: 8pt; text-align: left;">';

        $i = 0;
        foreach ($arguments as $argument) {
            if (count($arguments) > 1)
                $output .= "\n" . '<strong>#' . (++$i) . ' of ' . $total_arguments . '</strong>: ';

            // if argument is boolean, false value does not display, so ...
            if (is_bool($argument))
                $argument = ($argument) ? 'TRUE' : 'FALSE';
            else
                if (is_object($argument) && function_exists('array_reverse') && function_exists('class_parents'))
                    $output .= implode("\n" . '|' . "\n", array_reverse(class_parents($argument))) . "\n" . '|' . "\n";

            $output .= htmlspecialchars(print_r($argument, TRUE))
                . ((is_object($argument) && function_exists('spl_object_hash')) ? spl_object_hash($argument) : '');
        }
        $output .= "</pre>";
        $output .= "</fieldset>";

        self::$debug[] = $output;
    }

    /**
     * Get a value from $_POST / $_GET
     * if unavailable, take a default value
     *
     * @param string $key Value key
     * @param mixed $defaultValue (optional)
     * @param boolean $withcode allow html
     * @return mixed Value
     */
    public static function getValue($key, $defaultValue = false) {
        if (!isset($key) || (isset($key) && $key == '')) {
            return $defaultValue;
        }

        if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') {
            $ret = (isset($_POST[$key]) ? $_POST[$key] : (isset($_GET[$key]) ? $_GET[$key] : ''));
        } else {
            $ret = (isset($_GET[$key]) ? $_GET[$key] : '');
        }

        if (is_string($ret) && $ret <> '') {
            $ret = sanitize_text_field($ret);
        }

        if (!$ret) {
            return $defaultValue;
        } else {
            return wp_unslash($ret);
        }
    }


    /**
     * Check if the parameter is set
     *
     * @param string $key
     * @return boolean
     */
    public static function getIsset($key) {
        if (!isset($key) OR empty($key) OR !is_string($key))
            return false;

        return isset($_POST[$key]) ? true : (isset($_GET[$key]) ? true : false);
    }

    /**
     * Set the header type
     * @param string $type
     */
    public static function setHeader($type) {
        switch ($type) {
            case 'json':
                header('Content-Type: application/json');
        }
    }


    /**
     * Connect remote with CURL if exists
     *
     * @param string $url
     * @param array $param
     * @param array $options
     * @return bool|string
     */
    public static function ctlppu_remote_get($url, $param = array(), $options = array()) {
        $parameters = '';

        if (isset($param) && !empty($param))
            foreach ($param as $key => $value) {
                if (isset($key) && $key <> '' && $key <> 'timeout')
                    $parameters .= ($parameters == "" ? "" : "&") . $key . "=" . $value;
            }
        if ($parameters <> '')
            $url .= ((strpos($url, "?") === false) ? "?" : "&") . $parameters;

        $options['timeout'] = (isset($options['timeout'])) ? $options['timeout'] : 30;

        if (!$response = self::ctlppu_wpcall($url, $options)) {
            return false;
        }

        return $response;
    }

    /**
     * Use the WP remote call
     * @param string $url
     * @param array $options
     * @return string
     */
    private static function ctlppu_wpcall($url, $options) {
        $response = wp_remote_get($url, $options);
        if (is_wp_error($response)) {
            self::dump($response);
            return false;
        }

        $response = self::cleanResponce(wp_remote_retrieve_body($response)); //clear and get the body
        self::dump('wp_remote_get', $url, $options, $response); //output debug
        return $response;
    }

    /**
     * Get the Json from responce if any
     * @param string $response
     * @return string
     */
    private static function cleanResponce($response) {

        if (function_exists('substr_count'))
            if (substr_count($response, '(') > 1)
                return $response;
        return $response;

        if (strpos($response, '(') !== false && strpos($response, ')') !== false)
            $response = substr($response, (strpos($response, '(') + 1), (strpos($response, ')') - 1));

        return $response;
    }

    /**
     * Support for i18n with wpml, polyglot or qtrans
     *
     * @param string $in
     * @return string $in localized
     */
    public static function i18n($in) {
        if (function_exists('langswitch_filter_langs_with_message')) {
            $in = langswitch_filter_langs_with_message($in);
        }
        if (function_exists('polyglot_filter')) {
            $in = polyglot_filter($in);
        }
        if (function_exists('qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage')) {
            $in = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($in);
        }
        $in = apply_filters('localization', $in);
        return $in;
    }

    /**
     * Convert integer on the locale format.
     *
     * @param int $number The number to convert based on locale.
     * @param int $decimals Precision of the number of decimal places.
     * @return string Converted number in string format.
     */
    public static function i18n_number_format($number, $decimals = 0) {
        global $wp_locale;
        $formatted = number_format($number, absint($decimals), $wp_locale->number_format['decimal_point'], $wp_locale->number_format['thousands_sep']);
        return apply_filters('number_format_i18n', $formatted);
    }

    /**
     * Show the debug dump
     */
    public static function showDebug() {
        echo "Debug result: <br />" . '<div id="wpcontent">' . @implode('<br />', self::$debug) . '</div>';

        $run_time = number_format(microtime(true) - CTLPPU_REQUEST_TIME, 3);
        $pps = number_format(1 / $run_time, 0);
        $memory_avail = ini_get('memory_limit');
        $memory_used = number_format(memory_get_usage(true) / (1024 * 1024), 2);
        $memory_peak = number_format(memory_get_peak_usage(true) / (1024 * 1024), 2);

        echo PHP_EOL . " Load: {$memory_avail} (avail) / {$memory_used}M (used) / {$memory_peak}M (peak)";
        echo "  | Time: {$run_time}s | {$pps} req/sec";
    }

    public static function emptyCache() {
        if (function_exists('w3tc_pgcache_flush')) {
            w3tc_pgcache_flush();
        }
        if (function_exists('wp_cache_clear_cache')) {
            wp_cache_clear_cache();
        }
    }

    public static function checkUpgrade() {

    }


    /**
     * This hook will save the current version in database
     *
     * @return void
     */
    function hookInit() {
        //TinyMCE editor required
        //set_user_setting('editor', 'tinymce');

        $this->loadMultilanguage();

        //add setting link in plugin
        add_filter('plugin_action_links', array($this, 'hookActionlink'), 5, 2);

        add_action('save_post', array($this, 'hookSavePost'), 99);
    }

    public function hookSavePost() {
        self::saveOptions("last_update", 0);
    }

    /**
     * Load the multilanguage support from .mo
     */
    private function loadMultilanguage() {
        if (!defined('WP_PLUGIN_DIR')) {
            load_plugin_textdomain(_CTLPPU_PLUGIN_NAME_, _CTLPPU_PLUGIN_NAME_ . '/languages/');
        } else {
            load_plugin_textdomain(_CTLPPU_PLUGIN_NAME_, null, _CTLPPU_PLUGIN_NAME_ . '/languages/');
        }
    }

    /**
     * Add a link to settings in the plugin list
     *
     * @param array $links
     * @param type $file
     * @return array
     */
    public function hookActionlink($links, $file) {
        if ($file == _CTLPPU_PLUGIN_NAME_ . '/' . _CTLPPU_PLUGIN_NAME_ . '.php') {
            $link = '<a href="' . admin_url('admin.php?page=ctlppu_settings') . '">' . __('Settings', _CTLPPU_PLUGIN_NAME_) . '</a>';
            array_unshift($links, $link);
        }

        return $links;
    }

    public function ctlppu_activate() {
        set_transient('ctlppu_activate', true);
    }


    /**
     * Save the Options in user option table in DB
     *
     * @param null $key
     * @param string $value
     */
    public static function saveOptions($key = null, $value = '') {
        if (isset($key)) {
            self::$options[$key] = $value;
        }

        if (is_multisite()) {
            update_blog_option(get_current_blog_id(), _CTLPPU_OPTION_, json_encode(self::$options));
        } else {
            update_option(_CTLPPU_OPTION_, json_encode(self::$options));
        }
    }

}