from __future__ import annotations

import os
import time
import unittest
from unittest.mock import patch
from unittest.mock import MagicMock

from apps.aroflo_connector_app.ui_automation_worker.app import create_app
from apps.aroflo_connector_app.worker_security import sign_worker_request
from apps.aroflo_connector_app.worker_client import AroFloWorkerClient


class WorkerSecurityChecks(unittest.TestCase):
    def setUp(self):
        self.app = create_app()
        self.app.config["TESTING"] = True
        self.client = self.app.test_client()

    def test_worker_rejects_unsigned_request(self):
        response = self.client.get("/ui/session/status?tenant_id=tenant-a&bot_id=bot_a")
        self.assertEqual(401, response.status_code)

    @patch("apps.aroflo_connector_app.ui_automation_worker.routes.authenticate_worker_request")
    def test_worker_requires_bot_identity(self, authenticate):
        response = self.client.get("/ui/session/status?tenant_id=tenant-a")
        self.assertEqual(400, response.status_code)
        authenticate.assert_not_called()

    def test_signature_binds_method_path_body_timestamp_and_nonce(self):
        signature = sign_worker_request("secret", "POST", "/ui/session/connect", b"{}", "100", "nonce")
        self.assertNotEqual(signature, sign_worker_request("secret", "GET", "/ui/session/connect", b"{}", "100", "nonce"))
        self.assertNotEqual(signature, sign_worker_request("secret", "POST", "/ui/session/connect", b'{"x":1}', "100", "nonce"))

    def test_worker_client_sends_no_credentials_and_signs_exact_body(self):
        response = MagicMock(status_code=200)
        response.json.return_value = {"state": "ONLINE"}
        session = MagicMock()
        session.request.return_value = response
        client = AroFloWorkerClient("https://worker.example", "secret", session)
        result = client.call("POST", "/ui/session/connect", tenant_id="tenant-a", bot_id="bot_a")
        self.assertEqual("ONLINE", result["state"])
        kwargs = session.request.call_args.kwargs
        self.assertNotIn(b"password", kwargs["data"])
        self.assertIn("X-AroFlo-Signature", kwargs["headers"])


if __name__ == "__main__":
    unittest.main()
