<?php

class ITSEC_Malware_Scheduling_Scanner {
	public static function scan() {
		require_once( ITSEC_Core::get_core_dir() . '/modules/malware/class-itsec-malware-scanner.php' );

		$results = ITSEC_Malware_Scanner::scan();

		$settings = ITSEC_Modules::get_settings( 'malware-scheduling' );

		if ( ! $settings['email_notifications'] ) {
			return;
		}

		$subject = self::get_email_subject( $results );

		if ( empty( $subject ) ) {
			return;
		}

		$addresses = self::get_email_addresses( $settings['email_contacts'] );

		if ( empty( $addresses ) ) {
			$display = ini_set( 'display_errors', false );
			trigger_error( __( 'One or more malware issues were found by iThemes Security, but no user could be found to send the email notification to. Please update the Malware Scan Scheduling settings for iThemes Security so that email notifications are properly sent.', 'it-l10n-ithemes-security-pro' ) );
			ini_set( 'display_errors', $display );
			return;
		}

		$message = self::get_email_message( $results );
		$headers = array( 'Content-Type: text/html; charset=UTF-8' );

		foreach ( $addresses as $address ) {
			wp_mail( $address, $subject, $message, $headers );
		}
	}

	protected static function get_email_message( $results ) {
		$site_name = esc_html( get_bloginfo( 'name', 'display' ) );
		$url = esc_url( get_site_url() );

		if ( is_wp_error( $results ) ) {
			$message = '<p>' . sprintf( _x( 'An error occurred while running the scheduled malware scan on %1$s (%2$s):', 'site name (site url)', 'it-l10n-ithemes-security-pro' ), $site_name, $url ) . "</p>\n";
			$message .= '<p>' . sprintf( __( 'Error Message: %s', 'it-l10n-ithemes-security-pro' ), $results->get_error_message() ) . "</p>\n";
			$message .= '<p>' . sprintf( __( 'Error Code: <code>%s</code>', 'it-l10n-ithemes-security-pro' ), esc_html( $results->get_error_code() ) ) . "</p>\n";
		} else {
			$count = 0;

			if ( ! empty( $results['SYSTEM']['ERROR'] ) ) {
				$count += count( $results['SYSTEM']['ERROR'] );
			}
			if ( ! empty( $results['BLACKLIST']['WARN'] ) ) {
				$count += count( $results['BLACKLIST']['WARN'] );
			}
			if ( ! empty( $results['MALWARE']['WARN'] ) ) {
				$count += count( $results['MALWARE']['WARN'] );
			}

			$message = _n(
				'Sucuri\'s malware scanner found an issue when scanning %1$s (%2$s).',
				'Sucuri\'s malware scanner found issues when scanning %1$s (%2$s).',
				$count,
				'it-l10n-ithemes-security-pro'
			);
			$message = '<p>' . sprintf( $message, $site_name, $url ) . "</p>\n";
			$message .= "<br>\n";

			if ( ! empty( $results['MALWARE']['WARN'] ) ) {
				$message .= '<p>' . sprintf( __( 'Malware was found on the site. For full details, please log into <code>%s</code>, go to Security > Logs, and view the latest Malware Scan entry listed in the Security Log Data section.', 'it-l10n-ithemes-security-pro' ), $url ) . "</p>\n";
			}
			if ( ! empty( $results['SYSTEM']['ERROR'] ) ) {
				foreach ( (array) $results['SYSTEM']['ERROR'] as $error ) {
					$message .= '<p>' . sprintf( __( 'Possible Site Issue: %s', 'it-l10n-ithemes-security-pro' ), esc_html( $error ) ) . "</p>\n";
				}
			}
			if ( ! empty( $results['BLACKLIST']['WARN'] ) ) {
				foreach ( (array) $results['BLACKLIST']['WARN'] as $warning ) {
					$message .= '<p>' . sprintf( __( 'Site Blacklisted: %1$s (<a href="%2$s">details</a>)', 'it-l10n-ithemes-security-pro' ), esc_html( $warning[0] ), esc_url( $warning[1] ) ) . "</p>\n";
				}
			}
		}

		$message .= "<br>\n";
		$message .= '<p>' . sprintf( __( 'The iThemes Security Pro plugin on <code>%s</code> generated this email message.', 'it-l10n-ithemes-security-pro' ), $url ) . "</p>\n";

		return $message;
	}

	protected static function get_email_subject( $results ) {
		$url = esc_url( preg_replace( '|^https?://|i', '', get_site_url() ) );

		if ( is_wp_error( $results ) ) {
			return sprintf( __( 'Scheduled malware scan resulted in an error on %s', 'it-l10n-ithemes-security-pro' ), $url );
		} else if ( ! empty( $results['BLACKLIST']['WARN'] ) || ! empty( $results['MALWARE']['WARN'] ) ) {
			return sprintf( __( 'Scheduled malware scan found warnings on %s', 'it-l10n-ithemes-security-pro' ), $url );
		} else if ( ! empty( $results['SYSTEM']['ERROR'] ) ) {
			if ( ! preg_match( '/Unable to connect\./i', $results['SYSTEM']['ERROR'] ) ) {
				return sprintf( __( 'Scheduled malware scan found an error on %s', 'it-l10n-ithemes-security-pro' ), $url );
			}
		}

		return false;
	}

	protected static function get_email_addresses( $contacts ) {
		if ( empty( $contacts ) ) {
			// Select all roles that can manage the plugin when the setting is empty.

			$validator = ITSEC_Modules::get_validator( 'malware-scheduling' );

			$users_and_roles = $validator->get_available_admin_users_and_roles();
			$contacts = array_keys( $users_and_roles['roles'] );
		}


		$addresses = array();

		foreach ( $contacts as $contact ) {
			if ( (string) $contact === (string) intval( $contact ) ) {
				$users = array( get_userdata( $contact ) );
			} else {
				list( $prefix, $role ) = explode( ':', $contact, 2 );

				if ( empty( $role ) ) {
					continue;
				}

				$users = get_users( array( 'role' => $role ) );
			}

			foreach ( $users as $user ) {
				if ( is_object( $user ) && ! empty( $user->user_email ) ) {
					$addresses[] = $user->user_email;
				}
			}
		}

		$addresses = array_unique( $addresses );

		if ( ! empty( $addresses ) ) {
			return $addresses;
		}


		if ( is_callable( 'wp_roles' ) ) {
			$roles = wp_roles();
		} else {
			$roles = new WP_Roles();
		}

		foreach ( $roles->roles as $role => $details ) {
			if ( isset( $details['capabilities']['manage_options'] ) && ( true === $details['capabilities']['manage_options'] ) ) {
				$users = get_users( array( 'role' => $role ) );

				foreach ( $users as $user ) {
					if ( ! empty( $user->user_email ) ) {
						$addresses[] = $user->user_email;
					}
				}
			}
		}

		return $addresses;
	}
}
