<?php

declare(strict_types=1);

namespace BotGuard\Services\Detection\Modules;

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

/**
 * JavaScript execution module.
 *
 * The verification page runs a series of micro-probes (ES6 features, async/await,
 * Promise, event-loop ordering) and reports the results. A client that submits
 * with no JS evidence, or that fails probes a real engine would pass, is treated
 * as non-JS / automated. It also flags navigator.webdriver === true.
 */
final class JavaScriptModule extends AbstractModule
{
    public function key(): string
    {
        return 'javascript';
    }

    public function analyze(SignalBag $signals): ModuleResult
    {
        $js = $signals->clientArray('javascript');

        // Absolutely no JS payload => the page script never ran.
        if ($js === []) {
            return $this->scored(0.05, [], ['JavaScript did not execute'], ['present' => false]);
        }

        $enabled = (bool) ($js['enabled'] ?? false);
        $es6 = (bool) ($js['es6'] ?? false);
        $async = (bool) ($js['async'] ?? false);
        $promise = (bool) ($js['promise'] ?? false);
        $eventLoop = (bool) ($js['event_loop'] ?? false);
        $webdriver = (bool) ($js['webdriver'] ?? false);

        $this->detail('probes', $js);

        $this->check('JavaScript enabled', $enabled, 2.0);
        $this->check('ES6 supported', $es6, 1.0);
        $this->check('Async/await works', $async, 1.0);
        $this->check('Promise supported', $promise, 1.0);
        $this->check('Event loop ordering correct', $eventLoop, 1.0);

        // navigator.webdriver is the standard automation flag.
        $this->check('navigator.webdriver not set', ! $webdriver, 3.0);

        return $this->result();
    }
}
