<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * One detection within a security scan. Carries full forensic evidence
 * (file hash, process, network connection, persistence mechanism)
 * preserved for chain-of-custody — staff has everything needed to
 * justify a suspension or hand off to law enforcement BEFORE deciding
 * to act.
 */
class AgentSecurityFinding extends Model
{
    protected $table = 'agent_security_findings';

    // Detection categories — these mirror agent-side rule names so
    // operators reading the finding can trace it back to a specific
    // pattern. Add new ones here AND in resources/agent/agent-security.sh.
    public const CAT_CRYPTOJACK_PROCESS   = 'cryptojack_process';
    public const CAT_SUSPICIOUS_BINARY    = 'suspicious_binary';
    public const CAT_PERSISTENCE_CRON     = 'persistence_cron';
    public const CAT_PERSISTENCE_SHELL    = 'persistence_shell';
    public const CAT_OUTBOUND_MINING      = 'outbound_mining';
    public const CAT_MASQUERADED_PROCESS  = 'masqueraded_process';

    public const SEV_CRITICAL = 'critical';
    public const SEV_HIGH     = 'high';
    public const SEV_MEDIUM   = 'medium';
    public const SEV_LOW      = 'low';

    public const STATUS_DETECTED       = 'detected';
    public const STATUS_CONFIRMED      = 'confirmed';
    public const STATUS_FALSE_POSITIVE = 'false_positive';
    public const STATUS_SUSPENDED      = 'suspended';
    public const STATUS_RESOLVED       = 'resolved';

    protected $fillable = [
        'server_id', 'scan_id',
        'category', 'severity', 'unix_user',
        'file_path', 'file_hash_sha256', 'file_size_bytes', 'file_permissions',
        'process_pid', 'process_name', 'process_cmdline',
        'process_cpu_percent', 'process_rss_kb',
        'remote_ip', 'remote_port',
        'evidence', 'status',
        'reviewer_notes', 'reviewed_by_user_id',
        'detected_at', 'reviewed_at', 'resolved_at',
        'incident_id',
    ];

    protected $casts = [
        'evidence'             => 'array',
        'detected_at'          => 'datetime',
        'reviewed_at'          => 'datetime',
        'resolved_at'          => 'datetime',
        'process_cpu_percent'  => 'decimal:2',
    ];

    public function server(): BelongsTo  { return $this->belongsTo(Server::class); }
    public function scan(): BelongsTo    { return $this->belongsTo(AgentSecurityScan::class, 'scan_id'); }
    public function incident(): BelongsTo { return $this->belongsTo(Incident::class); }
    public function reviewer(): BelongsTo{ return $this->belongsTo(User::class, 'reviewed_by_user_id'); }

    /**
     * Severity rank for sorting / comparison. Higher = worse.
     */
    public function severityRank(): int
    {
        return match ($this->severity) {
            self::SEV_CRITICAL => 4,
            self::SEV_HIGH     => 3,
            self::SEV_MEDIUM   => 2,
            self::SEV_LOW      => 1,
            default            => 0,
        };
    }

    public function isOpen(): bool
    {
        return in_array($this->status, [
            self::STATUS_DETECTED, self::STATUS_CONFIRMED,
        ], true);
    }
}
