<?php

namespace routes;

use classes\authentication;
use classes\replication_manager;
use traits\route_t;

class superuserReplicationRoute
{
    use route_t;

    private const RETIRED_MANAGEMENT_MESSAGE = 'Replication management has been retired. Use System -> Database, System -> Redis, and System -> MinIO for read-only status.';

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

            $this->requireClassicSuperuserPermission('superuser_replication_view');
            $refresh = $this->toBool($this->getParameter('refresh'), false);
            $response->success((new replication_manager())->summary($refresh));
        }, [
            'superuser_replication_view' => 'View database, Redis, and MinIO replication topology and status',
        ]);

        $this->post('/superuser/replication/databases', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_manage');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_manage' => 'Add and manage database replication host credentials',
        ]);

        $this->post('/superuser/replication/redis', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_manage');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_manage' => 'Add and manage Redis replication host credentials',
        ]);

        $this->post('/superuser/replication/minio', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_manage');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_manage' => 'Add and manage MinIO replication host credentials',
        ]);

        $this->post('/superuser/replication/compose-template', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_manage');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_manage' => 'Generate Docker Compose templates for replication-ready database, Redis, and MinIO hosts',
        ]);

        $this->post('/superuser/replication/test-credentials', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_manage');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_manage' => 'Test database, Redis, and MinIO replication host credentials before saving them',
        ]);

        $this->post('/superuser/replication/{kind}/{id}/test', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_manage');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_manage' => 'Validate database, Redis, and MinIO replication host connectivity and privileges',
        ]);

        $this->post('/superuser/replication/{kind}/{id}/provision', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_manage');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_manage' => 'Provision a database, Redis, or MinIO host as a replica of the current primary',
        ]);

        $this->post('/superuser/replication/{kind}/{id}/promote', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_promote');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_promote' => 'Promote a healthy caught-up database, Redis, or MinIO replica to primary',
        ]);

        $this->patch('/superuser/replication/{kind}/{id}', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_manage');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_manage' => 'Rename database, Redis, and MinIO replication hosts',
        ]);

        $this->delete('/superuser/replication/{kind}/{id}', function () {
            $this->requireClassicSuperuserPermission('superuser_replication_remove');
            $this->rejectRetiredManagement();
        }, [
            'superuser_replication_remove' => 'Remove inactive prior hosts and unhealthy database, Redis, or MinIO replicas',
        ]);
    }

    /**
     * Replication controls alter infrastructure state and must only be used by
     * a classic superuser session. Subuser bearer tokens can carry a delegated
     * customer context via X-Customer-Number, so do not allow them to fall back
     * to plain string user permission checks for these routes.
     */
    private function requireClassicSuperuserPermission(string $permission): bool
    {
        global $response;

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

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

    private function rejectRetiredManagement(): void
    {
        global $response;

        $response->error(['message' => self::RETIRED_MANAGEMENT_MESSAGE], 410);
    }

    private function toBool(mixed $value, bool $default): bool
    {
        if (is_bool($value)) {
            return $value;
        }
        if ($value === null) {
            return $default;
        }
        $normalized = strtolower(trim((string)$value));
        if (in_array($normalized, ['1', 'true', 'yes', 'on'], true)) {
            return true;
        }
        if (in_array($normalized, ['0', 'false', 'no', 'off'], true)) {
            return false;
        }
        return $default;
    }
}
