<?php

declare(strict_types=1);

namespace BotGuard\Services\Detection\Modules;

use BotGuard\Helpers\UserAgentParser;
use BotGuard\Services\Detection\ModuleResult;
use BotGuard\Services\Detection\SignalBag;

/**
 * User-Agent analysis module.
 *
 * Inspects the UA string for: presence, plausibility, headless/automation
 * markers, known-bot signatures, and internal consistency (a modern browser UA
 * should name a browser + version + platform). A missing or automation UA is a
 * strong bot indicator.
 */
final class UserAgentModule extends AbstractModule
{
    public function key(): string
    {
        return 'user_agent';
    }

    public function analyze(SignalBag $signals): ModuleResult
    {
        $ua = $signals->userAgent();
        $parsed = UserAgentParser::parse($ua);

        $this->detail('user_agent', $ua);
        $this->detail('parsed', $parsed);

        // Presence.
        $this->check('User-Agent present', ! $parsed['empty'], 1.0);

        // Automation / headless markers are near-decisive: they must dominate so
        // that a headless build of an otherwise-real browser still scores low.
        $this->check('No headless/automation markers', ! $parsed['is_headless'], 6.0);

        // Known crawler/library signatures.
        $this->check('No known-bot signature', ! $parsed['is_bot'], 4.0);

        // Recognisable browser + platform.
        $this->check('Recognisable browser', $parsed['browser'] !== 'Unknown', 1.0);
        $this->check('Recognisable platform', $parsed['os'] !== 'Unknown', 0.5);

        // Version string present for the named browser.
        $this->check('Browser version present', $parsed['version'] !== '' || $parsed['browser'] === 'Unknown', 0.5);

        // Abnormal length (real UAs are ~40-220 chars).
        $len = strlen($ua);
        $this->check('Plausible UA length', $len >= 25 && $len <= 512, 0.5);

        // Mozilla token is present on essentially all real browser UAs.
        $this->check('Contains Mozilla token', $parsed['empty'] || str_contains(strtolower($ua), 'mozilla'), 0.5);

        return $this->result();
    }
}
