<?php

class SaleslooUpdater
{
    public $plugin_slug;
    public $version;
    public $cache_key;
    public $cache_allowed;
    public $file;
    public $server;
    public $plugin_info;

    /**
     * Instance.
     *
     * Holds the files instance.
     *
     * @since 1.0.0
     * @access public
     */
    public static $instance = null;

    /**
     * Init
     *
     * @since 1.0.0
     */
    public static function init($file)
    {
        if (is_null(self::$instance)) {
            self::$instance = new self($file);
        }

        return self::$instance;
    }

    /**
     * __construct
     *
     * @param  mixed $file
     * @return void
     */
    public function __construct($file)
    {
        $this->plugin_slug = 'salesloo';
        $this->file = $file;

        $this->plugin_info = get_file_data($this->file, ['Version' => 'Version', 'Name' => 'Plugin Name']);
        $this->version = $this->plugin_info['Version'];
        $this->cache_key = 'salesloo_updater';
        $this->cache_allowed = true;

        $this->hooks();
    }

    /**
     * hooks
     *
     * @return void
     */
    public function hooks()
    {
        add_filter('plugins_api', array($this, 'info'), 20, 3);
        add_filter('site_transient_update_plugins', array($this, 'update'));
        add_action('upgrader_process_complete', array($this, 'purge'), 10, 2);
        //add_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10, 3);

        // Display the link with the plugin action links.
        //add_filter('plugin_action_links', array($this, 'plugin_links'), 10, 3);

        // Display the link with the plugin meta.
        add_filter('plugin_row_meta', array($this, 'plugin_links'), 10, 4);
    }

    /**
     * Add a "details" link to open a thickbox popup with information about
     * the plugin from the public directory.
     *
     * @since 1.0.0
     *
     * @param array $links List of links.
     * @param string $plugin_file Relative path to the main plugin file from the plugins directory.
     * @param array $plugin_data Data from the plugin headers.
     * @return array
     */
    public function plugin_links($links, $plugin_file, $plugin_data = [])
    {
        if (!isset($plugin_data['slug']) && $plugin_file == 'salesloo/salesloo.php') {
            $links[] = sprintf(
                '<a href="%s" class="thickbox open-plugin-details-modal" aria-label="%s" data-title="%s">%s</a>',
                esc_url(network_admin_url('plugin-install.php?tab=plugin-information&plugin=salesloo&TB_iframe=true&width=600&height=550')),
                esc_attr(sprintf(__('More information about %s'), $plugin_data['Name'])),
                esc_attr($plugin_data['Name']),
                'View Details'
            );
        }

        return $links;
    }

    /**
     * request
     *
     * @return mixed
     */
    public function request()
    {

        $remote = get_transient($this->cache_key);
        $error_check_update = get_transient('error_check_update');

        if ($error_check_update) {
            return false;
        }

        if (false === $remote || !$this->cache_allowed) {

            $remote = wp_remote_get(
                'https://repo.salesloo.com/core',
                array(
                    'timeout' => 10,
                    'headers' => array(
                        'Accept' => 'application/json',
                        'Referer' => site_url()
                    )
                )
            );

            if (
                is_wp_error($remote)
                || 200 !== wp_remote_retrieve_response_code($remote)
                || empty(wp_remote_retrieve_body($remote))
            ) {
                set_transient('error_check_update', true, MINUTE_IN_SECONDS * 30);
                return false;
            }

            $remote = wp_remote_retrieve_body($remote);

            set_transient($this->cache_key, $remote, HOUR_IN_SECONDS);
        }

        $remote = json_decode($remote, false);

        //if (!isset($remote->version)) return false;

        return $remote;
    }


    function info($res, $action, $args)
    {

        // do nothing if you're not getting plugin information right now
        if ('plugin_information' !== $action) {
            return false;
        }

        // do nothing if it is not our plugin
        if ($this->plugin_slug !== $args->slug) {
            return false;
        }

        // get updates
        $remote = $this->request();

        if (!$remote) {
            return false;
        }

        $res = new stdClass();

        $res->name           = $remote->name;
        $res->slug           = $remote->slug;
        $res->version        = $remote->version;
        $res->tested         = $remote->tested;
        $res->requires       = $remote->requires;
        $res->author         = $remote->author;
        $res->author_profile = $remote->author_profile;
        $res->download_link  = $remote->download_url;
        $res->trunk          = $remote->download_url;
        $res->requires_php   = $remote->requires_php;
        $res->last_updated   = $remote->last_update;

        $res->sections = array(
            'description' => $remote->sections->description,
            'installation' => $remote->sections->installation,
            'changelog' => $remote->sections->changelog
        );

        if (!empty($remote->banners)) {
            $res->banners = array(
                'low' => $remote->banners->low,
                'high' => $remote->banners->high
            );
        }

        return $res;
    }

    public function update($transient)
    {

        if (empty($transient->checked)) {
            return $transient;
        }

        $remote = $this->request();

        if (
            $remote
            && version_compare($this->version, $remote->version, '<')
            && version_compare($remote->requires, get_bloginfo('version'), '<')
            && version_compare($remote->requires_php, PHP_VERSION, '<')
        ) {
            $res              = new stdClass();
            $res->slug        = $this->plugin_slug;
            $res->plugin      = plugin_basename($this->file);
            $res->new_version = $remote->version;
            $res->tested      = $remote->tested;
            $res->package     = $remote->download_url;

            $transient->response[$res->plugin] = $res;
        }

        return $transient;
    }

    public function purge($upgrader, $options)
    {

        if (
            $this->cache_allowed
            && 'update' === $options['action']
            && 'plugin' === $options['type']
        ) {
            // just clean the cache when new plugin version is installed
            delete_transient($this->cache_key);
        }
    }

    public function fixDirectoryName($source, $remoteSource, $upgrader)
    {
        global $wp_filesystem;
        /** @var WP_Filesystem_Base $wp_filesystem */

        //Basic sanity checks.
        if (!isset($source, $remoteSource, $upgrader, $upgrader->skin, $wp_filesystem)) {
            return $source;
        }

        //If WordPress is upgrading anything other than our plugin/theme, leave the directory name unchanged.
        if (!$this->is_being_upgraded($upgrader)) {
            return $source;
        }

        //Rename the source to match the existing directory.
        $correctedSource = trailingslashit($remoteSource) . $this->plugin_slug . '/';
        if ($source !== $correctedSource) {


            /** @var WP_Upgrader_Skin $upgrader ->skin */
            $upgrader->skin->feedback(sprintf(
                'Renaming %s to %s&#8230;',
                '<span class="code">' . $source . '</span>',
                '<span class="code">' . $correctedSource . '</span>'
            ));

            if (
                @rename($source, $correctedSource)
            ) {
                $upgrader->skin->feedback('Directory successfully renamed.');
                return $correctedSource;
            } else {
                return new WP_Error(
                    'error',
                    'Unable to rename the update to match the existing directory.'
                );
            }
        }

        return $source;
    }

    private function is_being_upgraded($upgrader)
    {
        if (!isset($upgrader, $upgrader->skin)) {
            return false;
        }

        $plugin_file = null;

        $skin = $upgrader->skin;
        if ($skin instanceof Plugin_Upgrader_Skin) {
            if (isset($skin->plugin) && is_string($skin->plugin) && ($skin->plugin !== '')) {
                $plugin_file = $skin->plugin;
            }
        } elseif (isset($skin->plugin_info) && is_array($skin->plugin_info)) {
            //This case is tricky because WP_Ajax_Upgrader_Skin (etc) doesn't actually store the plugin
            //filename anywhere. Instead, it has the plugin headers in $plugin_info. So the best we can
            //do is compare those headers to the headers of installed plugins.

            if ($skin->plugin_info['TextDomain'] == 'salesloo') return true;
        }

        if ($plugin_file == null) {
            return false;
        }

        if ($plugin_file != plugin_basename($this->file)) {
            return false;
        }

        return true;
    }
}
