<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class ASA_Diff_Scan {

	const OPTION_KEY = 'asa_snapshot_hashes';

	public function run() {
		$current = $this->build_snapshot();
		$prior   = get_option( self::OPTION_KEY, array() );
		$results = array();

		if ( empty( $prior ) ) {
			update_option( self::OPTION_KEY, $current, false );
			return array(
				array(
					'severity' => 'passed',
					'category' => 'file-diff',
					'title'    => 'File drift baseline created',
					'details'  => 'Initial file snapshot saved. Future manual scans will report actual drift from this baseline.',
				),
			);
		}

		$drift_events = array();

		foreach ( $current as $path => $hash ) {
			if ( ! isset( $prior[ $path ] ) ) {
				$results[] = array( 'severity' => 'low', 'category' => 'file-diff', 'title' => 'New file detected', 'details' => $path );
				$drift_events[] = array(
					'timestamp_gmt' => gmdate( 'Y-m-d H:i:s' ),
					'change_type'   => 'added',
					'path'          => ltrim( str_replace( ABSPATH, '', $path ), '/' ),
					'hash'          => $hash,
				);
			} elseif ( $prior[ $path ] !== $hash ) {
				$results[] = array( 'severity' => 'medium', 'category' => 'file-diff', 'title' => 'File changed', 'details' => $path );
				$drift_events[] = array(
					'timestamp_gmt' => gmdate( 'Y-m-d H:i:s' ),
					'change_type'   => 'changed',
					'path'          => ltrim( str_replace( ABSPATH, '', $path ), '/' ),
					'hash'          => $hash,
					'prior_hash'    => $prior[ $path ],
				);
			}
		}

		foreach ( $prior as $path => $hash ) {
			if ( ! isset( $current[ $path ] ) ) {
				$results[] = array( 'severity' => 'low', 'category' => 'file-diff', 'title' => 'File removed', 'details' => $path );
				$drift_events[] = array(
					'timestamp_gmt' => gmdate( 'Y-m-d H:i:s' ),
					'change_type'   => 'removed',
					'path'          => ltrim( str_replace( ABSPATH, '', $path ), '/' ),
					'prior_hash'    => $hash,
				);
			}
		}

		if ( ! empty( $drift_events ) ) {
			ASA_Telemetry::append_file_drift_events( $drift_events );
		}

		update_option( self::OPTION_KEY, $current, false );
		if ( empty( $results ) ) {
			$results[] = array( 'severity' => 'passed', 'category' => 'file-diff', 'title' => 'No file changes detected', 'details' => 'Current snapshot matches previous snapshot.' );
		}
		return $results;
	}

	private function build_snapshot() {
		$snapshot = array();
		$dirs     = array( WP_CONTENT_DIR . '/plugins', WP_CONTENT_DIR . '/themes', WP_CONTENT_DIR . '/uploads' );
		foreach ( $dirs as $dir ) {
			if ( ! is_dir( $dir ) ) {
				continue;
			}
			$iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS ) );
			foreach ( $iterator as $file ) {
				if ( ! $file->isFile() ) {
					continue;
				}
				$path = $file->getPathname();
				if ( filesize( $path ) > 1024 * 1024 * 3 ) {
					continue;
				}
				$snapshot[ $path ] = md5_file( $path );
			}
		}
		ksort( $snapshot );
		return $snapshot;
	}
}
