<?php

class Netbase_Plugins_Updater {

	private $authorize_token;

	private $plugin_params;

	private $plugin_data;

	public function __construct($plugin_params) {

		$this->plugin_params = $plugin_params;

		add_action( 'admin_init', array( $this, 'set_plugin_properties' ) );

		return $this;
	}

	public function set_plugin_properties() {

		$plugin_data = array();

		foreach($this->plugin_params as $current_plugin) {
			$plugin_data[$current_plugin['plugin_name']]['file'] 		= $current_plugin['file'];
			$plugin_data[$current_plugin['plugin_name']]['basename'] 	= plugin_basename($current_plugin['file']);
			$plugin_data[$current_plugin['plugin_name']]['active'] 		= is_plugin_active($current_plugin['file']);
			$plugin_data[$current_plugin['plugin_name']]['repository'] 	= $current_plugin['repository'];
		}

		$this->plugin_data = $plugin_data;

	}

	public function set_token( $token ) {
		$this->authorize_token = $token;
	}

	private function get_repository_info($options = array()) {
			
		$request_uri = sprintf('https://gitlab.com/api/v4/projects/%s/repository/tags?private_token=%s', $options['repository'], $this->authorize_token);

		$response = json_decode( wp_remote_retrieve_body( wp_remote_get( $request_uri ) ), true );

		if( is_array( $response ) ) {
			$response = current( $response );
		}

		return $response;
	}

	public function initialize() {
		add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'modify_transient' ), 10, 1 );
		add_filter( 'upgrader_source_selection', array( $this, 'rename_github_zip' ), 1, 4);
		add_filter( 'upgrader_post_install', array( $this, 'after_install' ), 10, 3 );
	}

	public function modify_transient( $transient ) {

		$checked = isset($transient->checked) ? $transient->checked : array();
		
		if( $checked ) {
			
			foreach($this->plugin_data as $current_plugin) {

				$current_basename 		= $current_plugin['basename'];

				$current_plugin_data 	= get_plugin_data( $current_plugin['file'] );

				$github_response 		= $this->get_repository_info($current_plugin);

				$out_of_date = version_compare( $github_response["name"], $checked[ $current_basename ], 'gt' );

				if( $out_of_date ) {

					$new_files = sprintf('https://gitlab.com/api/v4/projects/%s/repository/archive.zip?sha=%s&private_token=%s', $current_plugin['repository'], $github_response["name"], $this->authorize_token);

					$slug = current( explode('/', $current_basename ) );

					$plugin = array(
						'url' => $current_plugin_data["PluginURI"],
						'slug' => $slug,
						'package' => $new_files,
						'new_version' => $github_response["name"]
					);

					$transient->response[$current_basename] = (object) $plugin;
				}
			}
		}

		return $transient;
	}

	public function rename_github_zip( $source, $remote_source, $upgrade_meta, $extra_params )
	{
		if(isset($extra_params['plugin'])) {

			$plugin_source = explode('/', $extra_params['plugin']);
			$plugin_name = $plugin_source[0];

			if(isset($this->plugin_data[$plugin_name])) {
	
				if(  strpos( $source, $plugin_name) === false )
					return $source;
		
				$path_parts = pathinfo( $source );
				$newsource = trailingslashit( $path_parts['dirname'] ) . trailingslashit( $plugin_name );
				rename( $source, $newsource );
				return $newsource;
			}
			return $source;
		}
		return $source;
	}

	public function after_install( $response, $hook_extra, $result ) {

		if(isset($this->plugin_data[$result['destination_name']])) {

			$plugin_data_after_install = $this->plugin_data[$result['destination_name']];

			global $wp_filesystem;

			$install_directory = plugin_dir_path( $plugin_data_after_install['file'] );
			$wp_filesystem->move( $result['destination'], $install_directory );
			$result['destination'] = $install_directory;

			if ( $plugin_data_after_install['active'] ) {
				activate_plugin( $plugin_data_after_install['basename'] );
			}
		}

		return $result;
	}
}