"""Test the API for crashreports, devices, heartbeats and logfiles."""
import os
import tempfile

from django.contrib.auth.models import User
from django.urls import reverse

from rest_framework import status
from rest_framework.test import APIClient, APITestCase

from crashreports.models import Crashreport


class InvalidCrashTypeError(BaseException):
    """Invalid crash type encountered.

    The valid crash type values (strings) are:
      - 'crash';
      - 'smpl';
      - 'other'.

    Args:
      - crash_type: The invalid crash type.
    """

    def __init__(self, crash_type):
        """Initialise the exception using the crash type to build a message.

        Args:
            crash_type: The invalid crash type.
        """
        super(InvalidCrashTypeError, self).__init__(
            '{} is not a valid crash type'.format(crash_type))


class Dummy():
    """Dummy values for devices, heartbeats and crashreports."""

    DEFAULT_DUMMY_DEVICE_REGISTER_VALUES = {
        'board_date': '2015-12-15T01:23:45Z',
        'chipset': 'Qualcomm MSM8974PRO-AA',
    }

    DEFAULT_DUMMY_HEARTBEAT_VALUES = {
        'uuid': None,
        'app_version': 10100,
        'uptime': (
            'up time: 16 days, 21:49:56, idle time: 5 days, 20:55:04, '
            'sleep time: 10 days, 20:46:27'),
        'build_fingerprint': (
            'Fairphone/FP2/FP2:6.0.1/FP2-gms-18.03.1/FP2-gms-18.03.1:user/'
            'release-keys'),
        'radio_version': '4437.1-FP2-0-08',
        'date': '2018-03-19T09:58:30.386Z',
    }

    DEFAULT_DUMMY_CRASHREPORTS_VALUES = DEFAULT_DUMMY_HEARTBEAT_VALUES.copy()
    DEFAULT_DUMMY_CRASHREPORTS_VALUES.update({
        'is_fake_report': 0,
        'boot_reason': 'why?',
        'power_on_reason': 'it was powered on',
        'power_off_reason': 'something happened and it went off',
    })

    CRASH_TYPE_TO_BOOT_REASON_MAP = {
        'crash': Crashreport.BOOT_REASON_KEYBOARD_POWER_ON,
        'smpl': Crashreport.BOOT_REASON_RTC_ALARM,
        'other': 'whatever',
    }

    @staticmethod
    def _update_copy(original, update):
        """Merge fields of update into a copy of original."""
        data = original.copy()
        data.update(update)
        return data

    @staticmethod
    def device_register_data(**kwargs):
        """Return the data required to register a device.

        Use the values passed as keyword arguments or default to the ones
        from `Dummy.DEFAULT_DUMMY_DEVICE_REGISTER_VALUES`.
        """
        return Dummy._update_copy(
            Dummy.DEFAULT_DUMMY_DEVICE_REGISTER_VALUES, kwargs)

    @staticmethod
    def heartbeat_data(**kwargs):
        """Return the data required to create a heartbeat.

        Use the values passed as keyword arguments or default to the ones
        from `Dummy.DEFAULT_DUMMY_HEARTBEAT_VALUES`.
        """
        return Dummy._update_copy(Dummy.DEFAULT_DUMMY_HEARTBEAT_VALUES, kwargs)

    @staticmethod
    def crashreport_data(report_type=None, **kwargs):
        """Return the data required to create a crashreport.

        Use the values passed as keyword arguments or default to the ones
        from `Dummy.DEFAULT_DUMMY_CRASHREPORTS_VALUES`.

        Args:
            report_type (str, optional): A valid value from
                `Dummy.CRASH_TYPE_TO_BOOT_REASON_MAP.keys()` that will
                define the boot reason if not explicitly defined in the
                keyword arguments already.
        """
        data = Dummy._update_copy(
            Dummy.DEFAULT_DUMMY_CRASHREPORTS_VALUES, kwargs)
        if report_type and 'boot_reason' not in kwargs:
            if report_type not in Dummy.CRASH_TYPE_TO_BOOT_REASON_MAP:
                raise InvalidCrashTypeError(report_type)
            data['boot_reason'] = Dummy.CRASH_TYPE_TO_BOOT_REASON_MAP.get(
                report_type)
        return data


class DeviceRegisterAPITestCase(APITestCase):
    """Base class that offers a device registration method."""

    REGISTER_DEVICE_URL = "api_v1_register_device"

    def setUp(self):
        """Create an admin user for accessing the API.

        The APIClient that can be used to make authenticated requests to the
        server is stored in self.admin.
        """
        admin_user = User.objects.create_superuser(
            'somebody', 'somebody@example.com', 'thepassword')
        self.admin = APIClient()
        self.admin.force_authenticate(admin_user)

    def _register_device(self, **kwargs):
        """Register a new device.

        Arguments:
            **kwargs: The data to pass the dummy data creation
                method `Dummy.device_register_data`.
        Returns:
            (UUID, APIClient, str): The uuid of the new device as well as an
            authentication token and the associated user with credentials.

        """
        data = Dummy.device_register_data(**kwargs)
        response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        uuid = response.data['uuid']
        token = response.data['token']
        user = APIClient()
        user.credentials(HTTP_AUTHORIZATION='Token ' + token)

        return uuid, user, token


class DeviceTestCase(DeviceRegisterAPITestCase):
    """Test cases for registering devices."""

    def test_register(self):
        """Test registration of devices."""
        response = self.client.post(reverse(self.REGISTER_DEVICE_URL),
                                    Dummy.device_register_data())
        self.assertTrue("token" in response.data)
        self.assertTrue("uuid" in response.data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_create_missing_fields(self):
        """Test registration with missing fields."""
        response = self.client.post(reverse(self.REGISTER_DEVICE_URL))
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_missing_board_date(self):
        """Test registration with missing board date."""
        data = Dummy.device_register_data()
        data.pop('board_date')
        response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_missing_chipset(self):
        """Test registration with missing chipset."""
        data = Dummy.device_register_data()
        data.pop('chipset')
        response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_invalid_board_date(self):
        """Test registration with invalid board date."""
        data = Dummy.device_register_data()
        data['board_date'] = 'not_a_valid_date'
        response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_non_existent_time_board_date(self):
        """Test registration with non existing time.

        Test the resolution of a naive date-time in which the
        Europe/Amsterdam daylight saving time transition moved the time
        "forward". The server should not crash when receiving a naive
        date-time which does not exist in the server timezone or locale.
        """
        data = Dummy.device_register_data()
        # In 2017, the Netherlands changed from CET to CEST on March,
        # 26 at 02:00
        data['board_date'] = '2017-03-26 02:34:56'
        response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_create_ambiguous_time_board_date(self):
        """Test registration with ambiguous time.

        Test the resolution of a naive date-time in which the
        Europe/Amsterdam daylight saving time transition moved the time
        "backward". The server should not crash when receiving a naive
        date-time that can belong to multiple timezones.
        """
        data = Dummy.device_register_data()
        # In 2017, the Netherlands changed from CEST to CET on October,
        # 29 at 03:00
        data['board_date'] = '2017-10-29 02:34:56'
        response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)


class ListDevicesTestCase(DeviceRegisterAPITestCase):
    """Test cases for listing and deleting devices."""

    LIST_CREATE_URL = "api_v1_list_devices"
    RETRIEVE_URL = "api_v1_retrieve_device"

    def test_device_list(self):
        """Test registration of 2 devices."""
        number_of_devices = 2
        uuids = [
            str(self._register_device()[0])
            for _ in range(number_of_devices)
        ]

        response = self.admin.get(reverse(self.LIST_CREATE_URL), {})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), number_of_devices)
        for result in response.data['results']:
            self.assertIn(result['uuid'], uuids)

    def test_device_list_unauth(self):
        """Test listing devices without authentication."""
        response = self.client.get(reverse(self.LIST_CREATE_URL), {})
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_retrieve_device_auth(self):
        """Test retrieval of devices as admin user."""
        uuid, _, token = self._register_device()
        response = self.admin.get(reverse(self.RETRIEVE_URL, args=[uuid]), {})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['uuid'], str(uuid))
        self.assertEqual(response.data['token'], token)

    def test_retrieve_device_unauth(self):
        """Test retrieval of devices without authentication."""
        uuid, _, _ = self._register_device()
        response = self.client.get(reverse(self.RETRIEVE_URL, args=[uuid]), {})
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_delete_device_auth(self):
        """Test deletion of devices as admin user."""
        uuid, _, _ = self._register_device()
        url = reverse(self.RETRIEVE_URL, args=[uuid])
        response = self.admin.delete(url, {})
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        response = self.admin.delete(url, {})
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)


class HeartbeatListTestCase(DeviceRegisterAPITestCase):
    """Test cases for heartbeats."""

    LIST_CREATE_URL = "api_v1_heartbeats"
    RETRIEVE_URL = "api_v1_heartbeat"
    LIST_CREATE_BY_UUID_URL = "api_v1_heartbeats_by_uuid"
    RETRIEVE_BY_UUID_URL = "api_v1_heartbeat_by_uuid"

    @staticmethod
    def _create_dummy_data(**kwargs):
        return Dummy.heartbeat_data(**kwargs)

    def _post_multiple(self, client, data, count):
        return [
            client.post(reverse(self.LIST_CREATE_URL), data)
            for _ in range(count)]

    def _retrieve_single(self, user):
        count = 5
        response = self._post_multiple(self.admin, self.data, count)
        self.assertEqual(len(response), count)
        self.assertEqual(response[0].status_code, status.HTTP_201_CREATED)
        url = reverse(self.RETRIEVE_URL, args=[response[0].data['id']])
        request = user.get(url)
        return request.status_code

    def _retrieve_single_by_device(self, user):
        count = 5
        response = self._post_multiple(self.user, self.data, count)
        self.assertEqual(len(response), count)
        self.assertEqual(response[0].status_code, status.HTTP_201_CREATED)
        url = reverse(self.RETRIEVE_BY_UUID_URL, args=[
            self.uuid, response[0].data['device_local_id']])
        request = user.get(url)
        return request.status_code

    def setUp(self):
        """Set up a device and some data."""
        super().setUp()
        self.uuid, self.user, self.token = self._register_device()
        self.data = self._create_dummy_data(uuid=self.uuid)

    def test_create_no_auth(self):
        """Test creation without authentication."""
        noauth_client = APIClient()
        response = noauth_client.post(
            reverse(self.LIST_CREATE_URL), self.data)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_create_as_admin(self):
        """Test creation as admin."""
        response = self.admin.post(reverse(self.LIST_CREATE_URL), self.data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertTrue(response.data['id'] > 0)

    def test_create_as_admin_not_existing_device(self):
        """Test creation of heartbeat on non-existing device."""
        response = self.admin.post(
            reverse(self.LIST_CREATE_URL), self._create_dummy_data())
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

    def test_create_as_uuid_owner(self):
        """Test creation as owner."""
        response = self.user.post(
            reverse(self.LIST_CREATE_URL),
            self._create_dummy_data(uuid=self.uuid))
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['id'], -1)

    def test_create_as_uuid_not_owner(self):
        """Test creation as non-owner."""
        uuid, _, _ = self._register_device()
        response = self.user.post(
            reverse(self.LIST_CREATE_URL),
            self._create_dummy_data(uuid=uuid))
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

    def test_list(self):
        """Test listing of heartbeats."""
        count = 5
        self._post_multiple(self.user, self.data, count)
        response = self.admin.get(reverse(self.LIST_CREATE_URL))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), count)

    def test_retrieve_single_admin(self):
        """Test retrieval as admin."""
        self.assertEqual(
            self._retrieve_single(self.admin), status.HTTP_200_OK)

    def test_retrieve_single_device_owner(self):
        """Test retrieval as device owner."""
        self.assertEqual(
            self._retrieve_single(self.user), status.HTTP_403_FORBIDDEN)

    def test_retrieve_single_noauth(self):
        """Test retrieval without authentication."""
        noauth_client = APIClient()
        self.assertEqual(
            self._retrieve_single(noauth_client),
            status.HTTP_401_UNAUTHORIZED)

    def test_retrieve_single_by_device_admin(self):
        """Test retrieval by device as admin."""
        self.assertEqual(
            self._retrieve_single_by_device(self.admin), status.HTTP_200_OK)

    def test_retrieve_single_by_device_device_owner(self):
        """Test retrieval by device as owner."""
        self.assertEqual(
            self._retrieve_single_by_device(self.user),
            status.HTTP_403_FORBIDDEN)

    def test_retrieve_single_by_device_noauth(self):
        """Test retrieval by device without authentication."""
        noauth_client = APIClient()
        self.assertEqual(
            self._retrieve_single_by_device(noauth_client),
            status.HTTP_401_UNAUTHORIZED)

    def test_list_by_uuid(self):
        """Test listing of devices by UUID."""
        count = 5
        uuid, _, _ = self._register_device()
        self._post_multiple(self.user, self.data, count)
        self._post_multiple(
            self.admin, self._create_dummy_data(uuid=uuid), count)
        url = reverse(self.LIST_CREATE_BY_UUID_URL, args=[self.uuid])
        response = self.admin.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), count)

    def test_list_noauth(self):
        """Test listing of devices without authentication."""
        count = 5
        noauth_client = APIClient()
        self._post_multiple(self.user, self.data, count)
        response = noauth_client.get(reverse(self.LIST_CREATE_URL))
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_list_device_owner(self):
        """Test listing as device owner."""
        count = 5
        self._post_multiple(self.user, self.data, count)
        response = self.user.get(reverse(self.LIST_CREATE_URL))
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

    def test_no_radio_version(self):
        """Test creation and retrieval without radio version."""
        data = self._create_dummy_data(uuid=self.uuid)
        data.pop('radio_version')
        response = self.user.post(reverse(self.LIST_CREATE_URL), data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        url = reverse(self.LIST_CREATE_BY_UUID_URL, args=[self.uuid])
        response = self.admin.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), 1)
        self.assertIsNone(response.data['results'][0]['radio_version'])

    def test_radio_version_field(self):
        """Test retrieval of radio version field."""
        response = self.user.post(reverse(self.LIST_CREATE_URL), self.data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        url = reverse(self.LIST_CREATE_BY_UUID_URL, args=[self.uuid])
        response = self.admin.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), 1)
        self.assertEqual(response.data['results'][0]['radio_version'],
                         self.data['radio_version'])

    def test_send_non_existent_time(self):
        """Test sending of heartbeat with non existent time.

        Test the resolution of a naive date-time in which the
        Europe/Amsterdam daylight saving time transition moved the time
        "forward".
        """
        data = self._create_dummy_data(uuid=self.uuid)
        # In 2017, the Netherlands changed from CET to CEST on March,
        # 26 at 02:00
        data['date'] = '2017-03-26 02:34:56'
        response = self.user.post(reverse(self.LIST_CREATE_URL), data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

    def test_send_ambiguous_time(self):
        """Test sending of heartbeat with ambiguous time.

        Test the resolution of a naive date-time in which the
        Europe/Amsterdam daylight saving time transition moved the time
        "backward".
        """
        data = self._create_dummy_data(uuid=self.uuid)
        # In 2017, the Netherlands changed from CEST to CET on October,
        # 29 at 03:00
        data['date'] = '2017-10-29 02:34:56'
        response = self.user.post(reverse(self.LIST_CREATE_URL), data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)


# pylint: disable=too-many-ancestors
class CrashreportListTestCase(HeartbeatListTestCase):
    """Test cases for crash reports."""

    LIST_CREATE_URL = "api_v1_crashreports"
    RETRIEVE_URL = "api_v1_crashreport"
    LIST_CREATE_BY_UUID_URL = "api_v1_crashreports_by_uuid"
    RETRIEVE_BY_UUID_URL = "api_v1_crashreport_by_uuid"

    @staticmethod
    def _create_dummy_data(**kwargs):
        return Dummy.crashreport_data(**kwargs)


class LogfileUploadTest(DeviceRegisterAPITestCase):
    """Test cases for upload of log files."""

    LIST_CREATE_URL = "api_v1_crashreports"
    PUT_LOGFILE_URL = "api_v1_putlogfile_for_device_id"

    def _upload_crashreport(self, user, uuid):
        """
        Upload dummy crashreport data.

        Args:
            user: The user which should be used for uploading the report
            uuid: The uuid of the device to which the report should be uploaded

        Returns: The local id of the device for which the report was uploaded.

        """
        data = Dummy.crashreport_data(uuid=uuid)
        response = user.post(reverse(self.LIST_CREATE_URL), data)
        self.assertEqual(status.HTTP_201_CREATED, response.status_code)
        self.assertTrue('device_local_id' in response.data)
        device_local_id = response.data['device_local_id']

        return device_local_id

    def _test_logfile_upload(self, user, uuid):
        # Upload crashreport
        device_local_id = self._upload_crashreport(user, uuid)

        # Upload a logfile for the crashreport
        logfile = tempfile.NamedTemporaryFile('w+', suffix=".log", delete=True)
        logfile.write(u"blihblahblub")
        response = user.post(
            reverse(self.PUT_LOGFILE_URL, args=[
                uuid, device_local_id, os.path.basename(logfile.name)
            ]),
            {'file': logfile}, format="multipart")
        self.assertEqual(status.HTTP_201_CREATED, response.status_code)

    def test_logfile_upload_as_user(self):
        """Test upload of logfiles as device owner."""
        uuid, user, _ = self._register_device()
        self._test_logfile_upload(user, uuid)

    def test_logfile_upload_as_admin(self):
        """Test upload of logfiles as admin user."""
        uuid, _, _ = self._register_device()
        self._test_logfile_upload(self.admin, uuid)
