"""This module contains the test cases for the views of the api"""

import json
import os
import tempfile

from django.conf import settings
from django.core.urlresolvers import reverse
from django.test import override_settings

from rest_framework import status

import mtp
from mtp.apps.themes.models import Theme

from .test_cases import MTPAPITestCase


class UploadAPIViewTestCase(MTPAPITestCase):
    """Test cases for the ``upload`` api route"""

    @classmethod
    def tearDownClass(cls):
        """Remove test directory when finished"""

        super().tearDownClass()
        cls.clean_media()

    def test_upload_post(self):
        """Test that the ``upload`` route work"""

        file_content = 'file_content'.encode('utf-8')

        file = tempfile.NamedTemporaryFile()
        file.write(file_content)
        file.seek(0)

        params = {
            'post_params_1': 'content1',
            'post_params_2': 'content2',
            'post_params_3': 'content3',
        }
        files = {
            'post_file_1': file
        }

        folder_name = 'test'
        upload_url = reverse('api:upload_post', kwargs={'folder_name': folder_name})
        upload_data = dict(list(params.items()) + list(files.items()))

        response_raw = self.client.post(upload_url, upload_data)
        response = json.loads(response_raw.content.decode('utf-8'))

        test_folder = os.path.join(settings.UPLOAD_ROOT, folder_name)
        test_folder = os.path.join(test_folder, response['timestamp'])

        for key in params.keys():
            filename = os.path.join(test_folder, key)
            self.assertTrue(os.path.exists(filename))
            fp_test = open(filename)
            content = fp_test.read()
            self.assertEqual(content, params[key])

        for key in files.keys():
            filename = os.path.join(test_folder, key)
            self.assertTrue(os.path.exists(filename))
            fp_test = open(filename)
            content = fp_test.read()
            self.assertEqual(content, file_content.decode('utf-8'))

        # Cleanup
        file.close()


class DownloadsAPITestCase(MTPAPITestCase):
    """Test cases for the ``downloads`` api route"""

    @classmethod
    def setUpTestData(cls):
        """Set up the test data"""

        super().setUpTestData()

        cls.downloads_url = reverse('api:downloads', kwargs={'file_id': 'wtf-wtf'})

    def test_downloads_should_work(self):
        """Test that the ``downloads`` route work"""

        response = self.client.get(self.downloads_url)

        self.assertEqual(response.status_code, 200)


class GlobalSettingsViewForMasterMixin:
    """Base test case for the ``client_settings`` view."""

    expected_server_mode = None

    def test_global_settings_should_work(self):
        """Test that the ``client_settings`` output is correct"""

        response = self.client.get(reverse('apiv2:client_settings'))

        # The route work
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        default_theme = Theme.objects.non_deleted().get_default()

        # The output is correct
        self.assertEqual(
            response.data,
            {
                'ssl_enabled': settings.USE_SECURE_PROTOCOL_FOR_CURRENT,
                'server': settings.CURRENT_INSTANCE_HOST,
                'server_mode': self.expected_server_mode,
                'server_version': mtp.__version__,
                'mhr_version': settings.MHR_VERSION,
                'client_id': settings.CLIENT_NAME,
                'download_server': settings.CURRENT_INSTANCE_HOST,
                'url_message_broker': settings.MESSAGE_BROKER_WEBSOCKET_HOST,
                'port_message_broker': settings.MESSAGE_BROKER_WEBSOCKET_PORT,
                'default_theme_id': default_theme.pk if default_theme else None,
                'logmyass_websocket_url': settings.LOGMYASS_WEBSOCKET_URL,
                'logmyass_websocket_port': settings.LOGMYASS_WEBSOCKET_PORT,
            }
        )


@override_settings(INSTANCE_IS_SLAVE=False, INSTANCE_IS_MASTER=True)
class GlobalSettingsViewOnMasterTestCase(GlobalSettingsViewForMasterMixin, MTPAPITestCase):
    """Test cases for the ``client_settings`` view on a master"""

    expected_server_mode = 'saas'


@override_settings(INSTANCE_IS_SLAVE=True, INSTANCE_IS_MASTER=False)
class GlobalSettingsViewOnSlaveTestCase(GlobalSettingsViewForMasterMixin, MTPAPITestCase):
    """Test cases for the ``client_settings`` view on a slave"""

    expected_server_mode = 'local'
