<?php

class ITSEC_Malware_Scheduling {

	// Approximately 10 hours since first try
	const MAX_TRIES = 8;

	public function run() {
		add_action( 'itsec_scheduler_register_events', array( $this, 'register_event' ) );
		add_action( 'itsec_scheduled_malware-scan', array( $this, 'run_scan' ) );

		add_action( 'ithemes_sync_register_verbs', array( $this, 'register_sync_verbs' ) );
		add_filter( 'itsec-filter-itsec-get-everything-verbs', array( $this, 'register_sync_get_everything_verbs' ) );
		add_filter( 'itsec_notifications', array( $this, 'register_notification' ) );
		add_filter( 'itsec_malware-scheduling_notification_strings', array( $this, 'notification_strings' ) );
	}

	/**
	 * Run the malware scan.
	 *
	 * @param ITSEC_Job $job
	 */
	public function run_scan( $job ) {

		require_once( dirname( __FILE__ ) . '/class-itsec-malware-scheduling-scanner.php' );

		$results = ITSEC_Malware_Scheduling_Scanner::scan();

		if ( is_wp_error( $results ) && $results->get_error_message( 'itsec-scheduled-malware-scanner-sucuri-error' ) ) {
			$retry = $job->is_retry();

			if ( $retry > self::MAX_TRIES ) {
				ITSEC_Malware_Scheduling_Scanner::send_email( $results );
			} else {
				$job->reschedule_in( $this->minutes_until_retry( $retry + 1 ) );
			}
		}
	}

	/**
	 * Register the event.
	 *
	 * @param ITSEC_Scheduler $scheduler
	 */
	public function register_event( $scheduler ) {
		$scheduler->schedule( ITSEC_Scheduler::S_TWICE_DAILY, 'malware-scan' );
	}

	/**
	 * Determine the number of minutes we should wait before contacting Sucuri.
	 *
	 * Exponential back-off modified to have a minimum of 10 minute difference.
	 *
	 * [ ( 2ˣ-1 ) / 2 ] + 10x
	 *
	 * @param int $try Try count.
	 *
	 * @return int
	 */
	private function minutes_until_retry( $try ) {
		return (int) floor( ( ( pow(2, $try ) - 1 ) / 2 ) + ( 10 * $try ) );
	}

	/**
	 * Register verbs for Sync.
	 *
	 * @since 3.6.0
	 *
	 * @param Ithemes_Sync_API $api Sync API object.
	 */
	public function register_sync_verbs( $api ) {
		$api->register( 'itsec-get-malware-schedule-settings', 'Ithemes_Sync_Verb_ITSEC_Get_Malware_Schedule_Settings', dirname( __FILE__ ) . '/sync-verbs/itsec-get-malware-schedule-settings.php' );
		$api->register( 'itsec-manage-malware-schedule-settings', 'Ithemes_Sync_Verb_ITSEC_Manage_Malware_Schedule_Settings', dirname( __FILE__ ) . '/sync-verbs/itsec-manage-malware-schedule-settings.php' );
	}

	/**
	 * Filter to add verbs to the response for the itsec-get-everything verb.
	 *
	 * @since 3.6.0
	 *
	 * @param array $verbs
	 *
	 * @return array Array of verbs.
	 */
	public function register_sync_get_everything_verbs( $verbs ) {
		$verbs['malware_scheduling'][] = 'itsec-get-malware-schedule-settings';

		return $verbs;
	}

	/**
	 * Register the Scheduled Malware Scan notification.
	 *
	 * @param array $notifications
	 *
	 * @return array
	 */
	public function register_notification( $notifications ) {
		$notifications['malware-scheduling'] = array(
			'recipient' => ITSEC_Notification_Center::R_USER_LIST,
			'optional'  => true,
			'module'    => 'malware-scheduling',
		);

		return $notifications;
	}

	/**
	 * Register the strings for the Scheduled Malware Scan notification.
	 *
	 * @return array
	 */
	public function notification_strings() {
		return array(
			'label'       => esc_html__( 'Malware Scan Results', 'it-l10n-ithemes-security-pro' ),
			'description' => sprintf( esc_html__( 'The %1$sMalware Scan Scheduling%2$s module sends an email if it discovers an issue or has repeated difficulty conducting the scan.', 'it-l10n-ithemes-security-pro' ), '<a href="#" data-module-link="malware-scheduling">', '</a>' ),
		);
	}
}
