<?php
/*
* Define class pspPageSpeedInsightsAjax
* Make sure you skip down to the end of this file, as there are a few
* lines of code that are very important.
*/
!defined('ABSPATH') and exit;
if (class_exists('pspDashboard') != true) {
	global $psp;
	require_once( $psp->cfg['paths']['plugin_dir_path'] . 'modules/dashboard/init.php' );
}
if (class_exists('pspGTMetrixAjax') != true) {
    class pspGTMetrixAjax extends pspDashboard
    {
    	public $the_plugin = null;
		private $module_folder = null;
		private $file_cache_directory = '/psp-page-speed';
		private $cache_lifetime = 3600; // in seconds - 1 minute
		
		/*
        * Required __construct() function that initalizes the AA-Team Framework
        */
        public function __construct( $the_plugin=array() )
        {
        	$this->the_plugin = $the_plugin;
			$this->module_folder = $this->the_plugin->cfg['paths']['plugin_dir_url'] . 'modules/gtmetrix/';
			
			// ajax  helper
			add_action('wp_ajax_pspGTMetrixRequest', array( &$this, 'ajax_request' ));
		}
		
		/*
		* ajax_request, method
		* --------------------
		*
		* this will create requests to 404 table
		*/
		public function ajax_request()
		{
			$return = array();
			$actions = isset($_REQUEST['sub_actions']) ? explode(",", $_REQUEST['sub_actions']) : '';
			
			$retType = isset($_REQUEST['return']) ? $_REQUEST['return'] : '';

			//:: checkPage
			if( in_array( 'checkPage', array_values($actions)) ){
				
				// get page id by URL
				$page_url = get_permalink( (int) $_REQUEST['id'] );
				
				$checkPageRet = $this->check_page( $page_url, (int) $_REQUEST['id'] );
				
				$msg = isset($checkPageRet, $checkPageRet['msg']) && ! empty($checkPageRet['msg'])
					? 'Cannot connect to GTMetrix API. Please verify first that you\'ve setted the GTMetrix E-mail & API Key. Error message: ' . $checkPageRet['msg']
					: '';
				
				$return['checkPage'] = array(
					'status' => 'valid',
					'pagespeed_score' => $checkPageRet['pagespeed_score'],
					'yslow_score' 	=> $checkPageRet['yslow_score'],
					'first_paint_time' => $checkPageRet['first_paint_time'],
					'dom_content_loaded_time' => $checkPageRet['dom_content_loaded_time'],
					'page_load_time' => $checkPageRet['page_load_time'],
					'html_bytes' => $checkPageRet['html_bytes'],
					'page_bytes' => $checkPageRet['page_bytes'],
					'fully_loaded_time' => $checkPageRet['fully_loaded_time'],
					'connect_duration' => $checkPageRet['connect_duration'],
					'html_load_time' => $checkPageRet['html_load_time'],
					'resources' => $checkPageRet['resources'],
					'report_url' => $checkPageRet['report_url'],
					'remaining_credits' => $checkPageRet['remaining_credits'],
					'msg'	=> $msg,
				);
			}
			// end checkPage

			//:: viewSpeedRaportById
			if( in_array( 'viewSpeedRaportById', array_values($actions)) ){
				$html = array();
				$page_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
			}
			// end viewSpeedRaportById
			
			if ( $retType == 'array' ) {
				return $return;
			}
			die(json_encode($return));
		}
		
		public function check_page( $url='', $page_id=0 )
		{
			$settings = $this->the_plugin->getAllSettings( 'array', 'gtmetrix' );
			
			if ( !isset($settings['email']) ) $settings['email'] = '';
			if ( !isset($settings['api_key']) ) $settings['api_key'] = '';
			
			require_once( $this->the_plugin->cfg['paths']['plugin_dir_path'] . 'modules/gtmetrix/lib/gtmetrix-api.php' );
			$gtmetrix_connect = new Services_WTF_Test($settings['email'], $settings['api_key']);
			$api_status = $gtmetrix_connect->status();
			
			$remaining_credits = $api_status["api_credits"];
			$next_credits_refill = $api_status["api_refill"];
			
			$url_to_test = $url;
			
			$gtmetrix_testid = $gtmetrix_connect->test(array(
				'url' => $url_to_test,
				'location' => 4
			));
			$response = array();
			$msg = array();
			
			// try to get from db
			$db_response = get_post_meta( $page_id, 'gtmetrix_results', true );
			//var_dump('<pre>',$db_response ,'</pre>'); die(__FILE__ . ":" . __LINE__); 
			/*
			if ( $gtmetrix_testid ) {
				echo "Test started with: " . $gtmetrix_testid ."\r\n";
			}
			else {
				die("Test failed: " . $gtmetrix_connect->error()  ."\r\n");
			}
			*/
			
			// Other options include:
			//
			//      location => 4  - test from the Dallas test region (see locations below)
			//      login-user => 'foo',
			//      login-pass => 'bar',  - the test requires http authentication
			//      x-metrix-adblock => 1 - use the adblock plugin during this test
			//
			// For more information on options, see http://gtmetrix.com/api/

			// After calling the test method, your URL will begin testing. You can call:
			//echo "Waiting for test to finish" ."\r\n";
			
			$gtmetrix_connect->get_results();

			// which will block and return once your test finishes. Alternatively, can call:
			//     $state = $test->state() 
			// which will return the current state. Please don't check more than once per second.

			// Once your test is finished, chech that it completed ok, otherwise get the results.
			// Note: you must check twice. The first ->test() method can fail if url is malformed, or
			// other immediate error. However, if you get a job id, the test itself may fail if the url
			// can not be reached, or some pagespeed error.
			if ($gtmetrix_connect->error()) {
				//die($gtmetrix_connect->error());
				$msg[] = 'GTMETRIX connect error: ' . $gtmetrix_connect->error();
				$response['test_status'] = 'invalid';
			}
			
			$gtmetrix_testid = $gtmetrix_connect->get_test_id();
			
			//echo "Test completed succesfully with ID " . $gtmetrix_testid  ."<br />";
			$response = $gtmetrix_connect->results();
			$response['test_id'] = $gtmetrix_testid;
			
			if( is_array( $response ) && count( $response ) > 1 ) {
				update_post_meta( $page_id, 'gtmetrix_results', $response );
			}
			/*
			foreach ($results as $result => $data) {
				echo $result => $data" . "\r\n";
			}
			*/
			
			//echo "\nResources\n";
			$response['resources'] = array();
			$resources = $gtmetrix_connect->resources();
			
			if( is_array($resources) && count($resources) > 0 ) {
				foreach ($resources as $resource => $url) {
					//echo " Resource: " . $resource . ' ' . $url . "<br />";
					$response['resources'][$resource] = $url;
				}
			}
			

			// Each test has a unique test id. You can load an existing / old test result using:
			//echo "Loading test id" .  $gtmetrix_testid ."<br />";
			//$gtmetrix_connect->load($gtmetrix_testid);

			// If you no longer need a test, you can delete it:
			//echo "Deleting test id" . $gtmetrix_testid ."<br />";
			//$result = $gtmetrix_connect->delete();
			//if (! $result) { die("error deleting test: " . $gtmetrix_connect->error()); }

			// To list possible testing locations, use locations() method:
			/*
			echo  "\r\n" . "Locations GTmetrix can test from:" . "<br />";
			$locations = $gtmetrix_connect->locations();
			// Returns an array of associative arrays:
			foreach ($locations as $location) {
				echo "GTmetrix can run tests from: " . $location["name"] . " using id: " . $location["id"] . " default (" . $location["default"] . ")" ."<br />";
			}
			*/

			/* Sample output:

			Testing http://gtmetrix.com/
			Test started with PnV4kAr2
			Waiting for test to finish
			Test completed succesfully with ID PnV4kAr2
			  page_load_time => 480
			  html_bytes => 3346
			  page_elements => 16
			  report_url => http://gtmetrix.com/reports/gtmetrix.com/1r5AHf9E
			  html_load_time => 28
			  page_bytes => 90094
			  pagespeed_score => 95
			  yslow_score => 98

			Resources
			  Resource: report_pdf https://gtmetrix.com/api/0.1/test/PnV4kAr2/report-pdf
			  Resource: pagespeed https://gtmetrix.com/api/0.1/test/PnV4kAr2/pagespeed
			  Resource: har https://gtmetrix.com/api/0.1/test/PnV4kAr2/har
			  Resource: pagespeed_files https://gtmetrix.com/api/0.1/test/PnV4kAr2/pagespeed-files
			  Resource: yslow https://gtmetrix.com/api/0.1/test/PnV4kAr2/yslow
			  Resource: screenshot https://gtmetrix.com/api/0.1/test/PnV4kAr2/screenshot
			Loading test id PnV4kAr2
			Deleting test id PnV4kAr2

			Locations GTmetrix can test from:
			GTmetrix can run tests from: Vancouver, Canada using id: 1 default (1)
			GTmetrix can run tests from: London, UK using id: 2 default ()
			GTmetrix can run tests from: Sydney, Australia using id: 3 default ()
			GTmetrix can run tests from: Dallas, USA using id: 4 default ()
			GTmetrix can run tests from: Mumbai, India using id: 5 default ()

			*/
			
			$msg = implode( PHP_EOL, $msg );
			//var_dump('<pre>', $msg , '</pre>'); echo __FILE__ . ":" . __LINE__;die . PHP_EOL;
			//var_dump('<pre>',$response ,'</pre>'); die(__FILE__ . ":" . __LINE__); 
			
			//var_dump('<pre>',$resources ,'</pre>'); 
			return array(
				'status'		=> isset($response['test_id']) && $response['test_status'] != 'error' ? 'valid' : 'invalid',
				'pagespeed_score' => $response['pagespeed_score'],
				'yslow_score' 	=> $response['yslow_score'],
				'first_paint_time' => $response['first_paint_time'],
				'dom_content_loaded_time' => $response['dom_content_loaded_time'],
				'page_load_time' => $response['page_load_time'],
				'html_bytes' => $response['html_bytes'],
				'page_bytes' => $response['page_bytes'],
				'fully_loaded_time' => $response['fully_loaded_time'],
				'connect_duration' => $response['connect_duration'],
				'html_load_time' => $response['html_load_time'],
				'resources' => $response['resources'],
				'report_url' => $response['report_url'],
				'msg' 			=> $msg,
				'remaining_credits' => $remaining_credits
			);
		}
		
		private function formatBytes($bytes=0)
		{
		    if ($bytes >= 1073741824)
	        {
	            $bytes = number_format($bytes / 1073741824, 2) . ' GB';
	        }
	        elseif ($bytes >= 1048576)
	        {
	            $bytes = number_format($bytes / 1048576, 2) . ' MB';
	        }
	        elseif ($bytes >= 1024)
	        {
	            $bytes = number_format($bytes / 1024, 2) . ' KB';
	        }
	        elseif ($bytes > 1)
	        {
	            $bytes = $bytes . ' bytes';
	        }
	        elseif ($bytes == 1)
	        {
	            $bytes = $bytes . ' byte';
	        }
	        else
	        {
	            $bytes = '0 bytes';
	        }
	
	        return $bytes;
		}
    }
}