<?php
/**
 * Detection evidence.
 *
 * @package LocalGuardScanner
 */

namespace LocalGuardScanner\Domain\Detection;

use InvalidArgumentException;

/**
 * A detector's bounded, explainable observation.
 */
final class Evidence {
	const MAX_FRAGMENT_BYTES = 512;

	/** @var string */
	private $detector_id;
	/** @var int */
	private $weight;
	/** @var int */
	private $confidence;
	/** @var string */
	private $message_key;
	/** @var string */
	private $fragment;

	/**
	 * @param string $detector_id Detector ID.
	 * @param int    $weight      Weight from 0 to 100.
	 * @param int    $confidence  Confidence from 0 to 100.
	 * @param string $message_key Translation key.
	 * @param string $fragment    Redacted fragment.
	 */
	public function __construct( $detector_id, $weight, $confidence, $message_key, $fragment = '' ) {
		if ( '' === trim( $detector_id ) || '' === trim( $message_key ) ) {
			throw new InvalidArgumentException( 'Evidence requires detector and message identifiers.' );
		}
		if ( $weight < 0 || $weight > 100 || $confidence < 0 || $confidence > 100 ) {
			throw new InvalidArgumentException( 'Evidence weight and confidence must be between 0 and 100.' );
		}
		if ( strlen( $fragment ) > self::MAX_FRAGMENT_BYTES ) {
			throw new InvalidArgumentException( 'Evidence fragment is too large.' );
		}
		$this->detector_id = $detector_id;
		$this->weight      = (int) $weight;
		$this->confidence  = (int) $confidence;
		$this->message_key = $message_key;
		$this->fragment    = $fragment;
	}

	/** @return string */
	public function detector_id() {
		return $this->detector_id;
	}

	/** @return int */
	public function weight() {
		return $this->weight;
	}

	/** @return int */
	public function confidence() {
		return $this->confidence;
	}

	/** @return string */
	public function message_key() {
		return $this->message_key;
	}

	/** @return string */
	public function fragment() {
		return $this->fragment;
	}

	/** @return array<string,mixed> */
	public function to_array() {
		return array(
			'detector_id' => $this->detector_id,
			'weight'      => $this->weight,
			'confidence'  => $this->confidence,
			'message_key' => $this->message_key,
			'fragment'    => $this->fragment,
		);
	}
}
