# (c) cavaliba.com - tests / api

import json

import app_home.cache as cache
from app_data.data import Instance
from app_data.revision import revision_add_raw
from django.test import TestCase
from django.urls import reverse
from tests import helper


class APIKeyTest(TestCase):

    fixtures = ["test"]

    def setUp(self):
        cache.clear()

        # instance = Instance(classname="_apikey", keyname="key1")
        # data = {
        #     "secret": "secret1",
        #     "ip_filter": "*",
        #     "is_readonly": True,
        #     "is_enabled": True,
        #     "acl": "role_api_read",
        # }
        # instance.merge_import(data)
        # instance.create()

        # instance = Instance(classname="_apikey", keyname="key2")
        # data = {
        #     "secret": "secret2",
        #     "ip_filter": "",
        #     "is_readonly": False,
        #     "is_enabled": True,
        #     "acl": "role_api_admin",
        # }
        # instance.merge_import(data)
        # instance.create()


    # API HOME
    # --------

    def test_api_root(self):

        #helper.add_apikey_admin()
        response = self.client.get(reverse('api:api'))
        self.assertEqual(response.status_code, 401)


    def test_api_ping(self):
        #helper.add_apikey_admin()
        response = self.client.get(reverse('api:api_ping'))
        self.assertEqual(response.status_code, 200)


    def test_api_version(self):
        header = helper.add_apikey_admin()
        response = self.client.get(
            reverse('api:api_version'),
            headers=header,
        )
        self.assertEqual(response.status_code, 200)


    def test_api_version_output_formats(self):
        header = helper.add_apikey_admin()

        # Test JSON format (default)
        response = self.client.get(
            reverse('api:api_version'),
            headers=header,
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Type'], 'application/json; charset=utf-8')

        # Test JSON format (explicit)
        response = self.client.get(
            reverse('api:api_version') + '?o=json',
            headers=header,
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Type'], 'application/json; charset=utf-8')

        # Test YAML format
        response = self.client.get(
            reverse('api:api_version') + '?o=yaml',
            headers=header,
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Type'], 'application/x-yaml; charset=utf-8')

        # Test TXT format
        response = self.client.get(
            reverse('api:api_version') + '?o=txt',
            headers=header,
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Type'], 'text/plain; charset=utf-8')


    def test_api_key_disabled(self):
        instance = Instance(classname="_apikey", keyname="test")
        data = {
            "secret": "mysecret",
            "ip_filter": "*",
            "is_readonly": False,
            "is_enabled": False,
            "acl": "role_admin",
        }
        instance.merge_import(data)
        instance.create()

        response = self.client.get(
            reverse('api:api_version'),
            headers={"X-Cavaliba-Key": "test mysecret"},
        )
        self.assertEqual(response.status_code, 401)



    def test_api_badsecret(self):
        header = helper.add_apikey_admin()
        response = self.client.get(
            reverse('api:api_version'),
            headers={"X-Cavaliba-Key": "test badsecret"},
        )
        self.assertEqual(response.status_code, 401)



    # def test_api_readonly(self):

    #     response = self.client.post(
    #         reverse('app_home_api:api_version'),
    #         headers={"X-Cavaliba-Key": "key1 secret1"},
    #     )
    #     self.assertEqual(response.status_code, 401)


    # def test_auth_rw_ok(self):
    #     response = self.client.get(
    #         reverse('app_home_api:api_version'),
    #         headers={"X-Cavaliba-Key": "key2 secret2"},
    #     )
    #     self.assertEqual(response.status_code, 200)


    # API DATA
    # -----------

    # API IAM
    # -----------



    # API SIRENE
    # -----------


    # API IPAM
    # -----------

    # API STATUS
    # -----------


class APIAssetRevisionTest(TestCase):

    fixtures = ["test"]

    def setUp(self):
        cache.clear()
        self.header = helper.add_apikey_admin()
        helper.add_schema(classname="revtest")
        helper.add_instance(classname="revtest", keyname="obj01")
        for i in range(5):
            revision_add_raw(classname="revtest", keyname="obj01", action="edit")

    def test_api_asset_no_rev_param(self):
        response = self.client.get(
            reverse('api:api_asset', kwargs={'skey': 'revtest', 'key': 'obj01'}),
            headers=self.header,
        )
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertNotIn("_revision", data)

    def test_api_asset_rev_zero(self):
        response = self.client.get(
            reverse('api:api_asset', kwargs={'skey': 'revtest', 'key': 'obj01'}) + '?rev=0',
            headers=self.header,
        )
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertNotIn("_revision", data)

    def test_api_asset_rev_positive(self):
        response = self.client.get(
            reverse('api:api_asset', kwargs={'skey': 'revtest', 'key': 'obj01'}) + '?rev=3',
            headers=self.header,
        )
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertIn("_revision", data)
        self.assertEqual(len(data["_revision"]), 3)

    def test_api_asset_rev_entry_fields(self):
        response = self.client.get(
            reverse('api:api_asset', kwargs={'skey': 'revtest', 'key': 'obj01'}) + '?rev=1',
            headers=self.header,
        )
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        entry = data["_revision"][0]
        self.assertIn("login", entry)
        self.assertIn("date", entry)
        self.assertIn("action", entry)

    def test_api_asset_rev_capped_at_available(self):
        response = self.client.get(
            reverse('api:api_asset', kwargs={'skey': 'revtest', 'key': 'obj01'}) + '?rev=100',
            headers=self.header,
        )
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertEqual(len(data["_revision"]), 5)
