# -*- coding: utf-8 -*-

from edumfa.lib.policy import ACTION, SCOPE, delete_policy, set_policy

from .base import MyApiTestCase


class APISmsGatewayTestCase(MyApiTestCase):
    def test_01_crud_smsgateway(self):
        # list empty sms gateway definitions
        with self.app.test_request_context(
            "/smsgateway/", method="GET", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            detail = res.json.get("detail")
            self.assertEqual(result.get("value"), [])

        # check that we have an entry in the audit log
        audit_entry = self.find_most_recent_audit_entry(action="GET /smsgateway*")
        self.assertEqual(audit_entry["success"], 1, audit_entry)

        # create an sms gateway definition
        param = {
            "name": "myGW",
            "module": "edumfa.lib.smsprovider.SMSProvider.ISMSProvider",
            "description": "myGateway",
            "option.URL": "http://example.com",
        }
        with self.app.test_request_context(
            "/smsgateway", data=param, method="POST", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            detail = res.json.get("detail")
            self.assertEqual(result.get("value"), 1)

        # check the gateway
        with self.app.test_request_context(
            "/smsgateway/", method="GET", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            detail = res.json.get("detail")
            sms_gw = result.get("value")[0]
            self.assertEqual(sms_gw.get("description"), "myGateway")
            self.assertEqual(sms_gw.get("name"), "myGW")
            self.assertEqual(sms_gw.get("id"), 1)
            self.assertEqual(
                sms_gw.get("providermodule"),
                "edumfa.lib.smsprovider.SMSProvider.ISMSProvider",
            )
            self.assertEqual(sms_gw.get("options").get("URL"), "http://example.com")

        # update
        param = {
            "name": "myGW",
            "module": "edumfa.lib.smsprovider.SMSProvider.ISMSProvider",
            "description": "new description",
            "id": 1,
        }

        with self.app.test_request_context(
            "/smsgateway", data=param, method="POST", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            detail = res.json.get("detail")
            self.assertEqual(result.get("value"), 1)

        # check the gateway
        with self.app.test_request_context(
            "/smsgateway/1", method="GET", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            detail = res.json.get("detail")
            sms_gw = result.get("value")[0]
            self.assertEqual(sms_gw.get("description"), "new description")

        # delete gateway
        with self.app.test_request_context(
            "/smsgateway/myGW", method="DELETE", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            detail = res.json.get("detail")
            self.assertEqual(result.get("value"), 1)

        # list empty gateways
        with self.app.test_request_context(
            "/smsgateway/", method="GET", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            detail = res.json.get("detail")
            self.assertEqual(result.get("value"), [])

    def test_02_test_options(self):
        # create an sms gateway configuration
        param = {
            "name": "myGW",
            "module": "edumfa.lib.smsprovider.SMSProvider.ISMSProvider",
            "description": "myGateway",
            "option.URL": "http://example.com",
            "header.header1": "headervalue1",
        }
        with self.app.test_request_context(
            "/smsgateway", data=param, method="POST", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            self.assertGreaterEqual(result.get("value"), 1, result)
            smsgw_id = result.get("value")

        # add option
        param["option.HTTP_METHOD"] = "POST"
        # add header
        param["header.header2"] = "headervalue2"
        param["id"] = smsgw_id
        with self.app.test_request_context(
            "/smsgateway", method="POST", data=param, headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)

        # check options and headers
        with self.app.test_request_context(
            "/smsgateway/", method="GET", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            sms_gw = result.get("value")[0]
            self.assertEqual(sms_gw.get("options").get("URL"), "http://example.com")
            self.assertEqual(sms_gw.get("options").get("HTTP_METHOD"), "POST")
            self.assertEqual(sms_gw.get("headers").get("header1"), "headervalue1")
            self.assertEqual(sms_gw.get("headers").get("header2"), "headervalue2")

        # delete option "URL"
        with self.app.test_request_context(
            "/smsgateway/option/{0!s}/option.URL".format(smsgw_id),
            method="DELETE",
            headers={"Authorization": self.at},
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)

        # try to delete header "header1" at the wrong endpoint
        with self.app.test_request_context(
            "/smsgateway/option/{0!s}/option.header1".format(smsgw_id),
            method="DELETE",
            headers={"Authorization": self.at},
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 404, res)

        # delete header "header1"
        with self.app.test_request_context(
            "/smsgateway/option/{0!s}/header.header1".format(smsgw_id),
            method="DELETE",
            headers={"Authorization": self.at},
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)

        # check options
        with self.app.test_request_context(
            "/smsgateway/", method="GET", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            result = res.json.get("result")
            sms_gw = result.get("value")[0]
            self.assertEqual(sms_gw.get("options").get("URL"), None)
            self.assertEqual(sms_gw.get("options").get("HTTP_METHOD"), "POST")
            self.assertEqual(sms_gw.get("headers").get("header1"), None)
            self.assertEqual(sms_gw.get("headers").get("header2"), "headervalue2")

    def test_04_sms_provider_modules(self):
        with self.app.test_request_context(
            "/smsgateway/providers", method="GET", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            value = res.json.get("result").get("value")
            self.assertEqual(len(value), 7)
            self.assertTrue(
                "edumfa.lib.smsprovider.HttpSMSProvider.HttpSMSProvider" in value
            )
            self.assertTrue(
                "edumfa.lib.smsprovider.SmtpSMSProvider.SmtpSMSProvider" in value
            )
            self.assertTrue(
                "edumfa.lib.smsprovider.SipgateSMSProvider.SipgateSMSProvider" in value
            )
            self.assertTrue(
                "edumfa.lib.smsprovider.SmppSMSProvider.SmppSMSProvider" in value
            )
            self.assertIn(
                "edumfa.lib.smsprovider.ScriptSMSProvider.ScriptSMSProvider", value
            )
            self.assertIn(
                "edumfa.lib.smsprovider.HttpMessageToUidProvider"
                ".HttpMessageToUidProvider",
                value,
            )
            http_parameters = value.get(
                "edumfa.lib.smsprovider.HttpSMSProvider.HttpSMSProvider"
            )
            smtp_parameters = value.get(
                "edumfa.lib.smsprovider.SmtpSMSProvider.SmtpSMSProvider"
            )
            sipgate_parameters = value.get(
                "edumfa.lib.smsprovider.SipgateSMSProvider.SipgateSMSProvider"
            )
            smpp_parameters = value.get(
                "edumfa.lib.smsprovider.SmppSMSProvider.SmppSMSProvider"
            )
            msg2uid_parameters = value.get(
                "edumfa.lib.smsprovider."
                "HttpMessageToUidProvider.HttpMessageToUidProvider"
            )
            self.assertEqual(http_parameters.get("options_allowed"), True)
            self.assertEqual(smtp_parameters.get("options_allowed"), False)
            self.assertEqual(sipgate_parameters.get("options_allowed"), False)
            self.assertEqual(smpp_parameters.get("options_allowed"), False)
            self.assertTrue("URL" in http_parameters.get("parameters"))
            self.assertTrue("PROXY" in http_parameters.get("parameters"))
            self.assertTrue("HTTP_METHOD" in http_parameters.get("parameters"))
            self.assertTrue("URL" in msg2uid_parameters.get("parameters"))
            self.assertTrue(
                "UID_TOKENINFO_ATTRIBUTE" in msg2uid_parameters.get("parameters")
            )
            self.assertTrue("POST_CHECK_URL" in msg2uid_parameters.get("parameters"))

    def test_05_read_write_policies(self):
        set_policy(name="pol_read", scope=SCOPE.ADMIN, action=ACTION.SMSGATEWAYREAD)
        # create an sms gateway configuration
        param = {
            "name": "myGW",
            "module": "edumfa.lib.smsprovider.SMSProvider.ISMSProvider",
            "description": "myGateway",
            "option.URL": "http://example.com",
        }
        with self.app.test_request_context(
            "/smsgateway", data=param, method="POST", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 403, res)

        # Now we create a write policy, and we are allowed to write
        set_policy(name="pol_write", scope=SCOPE.ADMIN, action=ACTION.SMSGATEWAYWRITE)
        with self.app.test_request_context(
            "/smsgateway", data=param, method="POST", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)

        # delete the read policy
        delete_policy("pol_read")

        with self.app.test_request_context(
            "/smsgateway/", method="GET", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 403, res)

        # delete the write policy
        delete_policy("pol_write")

        # and delete sms gateway
        with self.app.test_request_context(
            "/smsgateway/myGW", method="DELETE", headers={"Authorization": self.at}
        ):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
