<?php
/**
 * Public scan failure catalog.
 *
 * @package LocalGuardScanner
 */

namespace LocalGuardScanner\Application\Scan;

/**
 * Maps internal failure points to safe, translatable administrator guidance.
 */
final class ScanFailureCatalog {
	/**
	 * @param string $code Failure code.
	 * @return array{code:string,stage:string,operation:string,message:string}
	 */
	public static function describe( $code ) {
		$code = self::sanitize_code( $code );
		$map  = array(
			'LGS-LOCK-LOST'         => array( 'scan', __( 'Maintain the scan lock', 'localguard-scanner' ), __( 'The scanner could not confirm ownership of the next batch.', 'localguard-scanner' ) ),
			'LGS-CURSOR-INVALID'    => array( 'scan', __( 'Read the saved checkpoint', 'localguard-scanner' ), __( 'The saved scan checkpoint was invalid or had changed.', 'localguard-scanner' ) ),
			'LGS-STATE-READ'        => array( 'scan', __( 'Read scan state', 'localguard-scanner' ), __( 'The saved scan state could not be read.', 'localguard-scanner' ) ),
			'LGS-STATE-WRITE'       => array( 'scan', __( 'Save scan state', 'localguard-scanner' ), __( 'The next safe checkpoint could not be stored.', 'localguard-scanner' ) ),
			'LGS-DISCOVERY'         => array( 'discovering', __( 'Prepare the inventory', 'localguard-scanner' ), __( 'The inventory totals could not be prepared.', 'localguard-scanner' ) ),
			'LGS-INV-WRITE'         => array( 'scanning_files', __( 'Save file inventory', 'localguard-scanner' ), __( 'The file inventory for the next batch could not be stored.', 'localguard-scanner' ) ),
			'LGS-DB-WRITE'          => array( 'scanning_database', __( 'Save database inventory', 'localguard-scanner' ), __( 'The database inventory for the next batch could not be stored.', 'localguard-scanner' ) ),
			'LGS-FINDING-WRITE'     => array( 'scan', __( 'Save a finding', 'localguard-scanner' ), __( 'A finding from the next batch could not be stored.', 'localguard-scanner' ) ),
			'LGS-FINDING-RECONCILE' => array( 'classifying', __( 'Check previous findings', 'localguard-scanner' ), __( 'Previous findings could not be reconciled safely.', 'localguard-scanner' ) ),
			'LGS-METADATA'          => array( 'scan', __( 'Encode scanner metadata', 'localguard-scanner' ), __( 'Scanner-owned progress metadata could not be encoded.', 'localguard-scanner' ) ),
			'LGS-DETECTOR'          => array( 'scan', __( 'Inspect the next batch', 'localguard-scanner' ), __( 'A detector could not complete the next batch safely.', 'localguard-scanner' ) ),
			'LGS-UNEXPECTED'        => array( 'scan', __( 'Complete the next batch', 'localguard-scanner' ), __( 'The next batch stopped because of an unexpected local error.', 'localguard-scanner' ) ),
		);
		if ( ! isset( $map[ $code ] ) ) {
			$code = 'LGS-UNEXPECTED';
		}
		return array(
			'code'      => $code,
			'stage'     => $map[ $code ][0],
			'operation' => $map[ $code ][1],
			'message'   => $map[ $code ][2],
		);
	}

	/** @param mixed $code Failure code. @return string */
	public static function sanitize_code( $code ): string {
		$code = is_string( $code ) ? strtoupper( $code ) : '';
		return 1 === preg_match( '/^LGS-[A-Z0-9-]{3,27}$/', $code ) ? $code : 'LGS-UNEXPECTED';
	}

	/** @param mixed $stage Failure stage. @return string */
	public static function sanitize_stage( $stage ): string {
		$allowed = array( 'queued', 'discovering', 'scanning_files', 'scanning_database', 'classifying', 'scan' );
		return is_string( $stage ) && in_array( $stage, $allowed, true ) ? $stage : 'scan';
	}
}
