<?php

namespace routes;

use classes\authentication;
use classes\security_policy_service;
use Throwable;
use traits\route_t;

require_once WD . '/classes/security_policy_service.php';

class superuserSecurityRoute
{
    use route_t;

    public function run(): void
    {
        $this->get('/superuser/system/security/summary', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_view');
            $response->success((new security_policy_service())->summary());
        }, [
            'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents',
        ]);

        $this->get('/superuser/system/security/settings', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_view');
            $response->success((new security_policy_service())->settings());
        }, [
            'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents',
            'superuser_security_limits_exempt' => 'Exempt requests from observe-mode security limit incidents',
        ]);

        $this->patch('/superuser/system/security/settings', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_settings_manage');
            try {
                $response->success((new security_policy_service())->updateSettings(
                    $this->getParametersAsArray(),
                    $this->actorUserId()
                ));
            } catch (Throwable $throwable) {
                $response->error(['message' => $throwable->getMessage()], 400);
            }
        }, [
            'superuser_security_settings_manage' => 'Configure observe-mode security thresholds and exemptions',
        ]);

        $this->get('/superuser/system/security/firewall-rules', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_view');
            $response->success((new security_policy_service())->listFirewallRules($this->getParametersAsArray()));
        }, [
            'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents',
        ]);

        $this->post('/superuser/system/security/firewall-rules', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_firewall_manage');
            try {
                $response->success((new security_policy_service())->createFirewallRule(
                    $this->getParametersAsArray(),
                    $this->actorUserId()
                ), 201);
            } catch (Throwable $throwable) {
                $response->error(['message' => $throwable->getMessage()], 400);
            }
        }, [
            'superuser_security_firewall_manage' => 'Create, update, and delete application firewall rules',
        ]);

        $this->patch('/superuser/system/security/firewall-rules/{id}', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_firewall_manage');
            try {
                $response->success((new security_policy_service())->updateFirewallRule(
                    $this->routeId(),
                    $this->getParametersAsArray(),
                    $this->actorUserId()
                ));
            } catch (Throwable $throwable) {
                $response->error(['message' => $throwable->getMessage()], 400);
            }
        }, [
            'superuser_security_firewall_manage' => 'Create, update, and delete application firewall rules',
        ]);

        $this->delete('/superuser/system/security/firewall-rules/{id}', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_firewall_manage');
            try {
                $response->success((new security_policy_service())->deleteFirewallRule(
                    $this->routeId(),
                    $this->actorUserId()
                ));
            } catch (Throwable $throwable) {
                $response->error(['message' => $throwable->getMessage()], 400);
            }
        }, [
            'superuser_security_firewall_manage' => 'Create, update, and delete application firewall rules',
        ]);

        $this->get('/superuser/system/security/incidents', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_view');
            $response->success((new security_policy_service())->listIncidents($this->getParametersAsArray()));
        }, [
            'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents',
        ]);

        $this->get('/superuser/system/security/incidents/{id}', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_view');
            try {
                $response->success((new security_policy_service())->incidentDetail($this->routeId()));
            } catch (Throwable $throwable) {
                $response->error(['message' => $throwable->getMessage()], 404);
            }
        }, [
            'superuser_security_view' => 'View superuser security settings, firewall rules, and incidents',
        ]);

        $this->patch('/superuser/system/security/incidents/{id}', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_incidents_manage');
            try {
                $response->success((new security_policy_service())->updateIncident(
                    $this->routeId(),
                    $this->getParametersAsArray(),
                    $this->actorUserId()
                ));
            } catch (Throwable $throwable) {
                $response->error(['message' => $throwable->getMessage()], 400);
            }
        }, [
            'superuser_security_incidents_manage' => 'Acknowledge, resolve, reopen, and note security incidents',
        ]);

        $this->post('/superuser/system/security/incidents/{id}/notes', function () {
            global $response;

            $this->requireClassicSuperuserPermission('superuser_security_incidents_manage');
            try {
                $parameters = $this->getParametersAsArray();
                $response->success((new security_policy_service())->addIncidentNote(
                    $this->routeId(),
                    (string)($parameters['note'] ?? ''),
                    $this->actorUserId()
                ), 201);
            } catch (Throwable $throwable) {
                $response->error(['message' => $throwable->getMessage()], 400);
            }
        }, [
            'superuser_security_incidents_manage' => 'Acknowledge, resolve, reopen, and note security incidents',
        ]);
    }

    private function requireClassicSuperuserPermission(string $permission): bool
    {
        global $response;

        if ((new authentication())->get_subuser() !== false) {
            $response->error('Subuser sessions cannot manage security controls.', 403);
        }

        return $this->requirePermission($permission);
    }

    private function routeId(): int
    {
        $id = (int)$this->fromRoute('id');
        $this->requireParameterIntPositive($id, 'id');
        return $id;
    }

    private function actorUserId(): ?int
    {
        try {
            $user = (new authentication())->get_user();
            return $user !== false && isset($user->id) ? (int)$user->id : null;
        } catch (Throwable) {
            return null;
        }
    }
}
