import os

import boto3
import requests
from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase

from vbv_lernwelt.core.models import User
from vbv_lernwelt.files.integrations import (
    s3_delete_file,
    s3_generate_presigned_post,
    s3_generate_presigned_url,
    s3_get_client,
)


class TestIntegrationsIntegrationTest(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.s3_client = s3_get_client()

    def setUp(self):
        self.user = User.objects.create(username="testuser")

        # Creating a dummy file for upload
        self.dummy_file = SimpleUploadedFile(
            "testfile.txt", b"these are the file contents!"
        )

    def test_s3_generate_presigned_post(self):
        # Test generating a presigned POST for file upload
        presigned_post_data = s3_generate_presigned_post(
            file_path=f"{self.user.id}/testfile.txt",
            file_type="text/plain",
            file_name="testfile.txt",
        )
        self.assertIn("url", presigned_post_data)
        self.assertIn("fields", presigned_post_data)

        # Upload file using the presigned URL
        files = {"file": self.dummy_file}
        response = requests.post(
            presigned_post_data["url"], data=presigned_post_data["fields"], files=files
        )
        self.assertEqual(response.status_code, 204)

    def test_s3_generate_presigned_url(self):
        # First, manually upload a file to S3 for testing
        self.s3_client.upload_fileobj

        self.s3_client.upload_fileobj(
            self.dummy_file, settings.AWS_STORAGE_BUCKET_NAME, "testfile.txt"
        )

        # Test generating a presigned URL for the uploaded file
        presigned_url = s3_generate_presigned_url(file_path="testfile.txt")
        response = requests.get(presigned_url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content, b"these are the file contents!")

    def test_s3_delete_file(self):
        # Upload a file to S3 for testing
        self.s3_client.upload_fileobj(
            self.dummy_file, settings.AWS_STORAGE_BUCKET_NAME, "testfile.txt"
        )

        # Test deleting the file
        s3_delete_file(file_path="testfile.txt")
        # Assert that the file no longer exists
        with self.assertRaises(boto3.exceptions.botocore.client.ClientError):
            self.s3_client.head_object(
                Bucket=settings.AWS_STORAGE_BUCKET_NAME, Key="testfile.txt"
            )

    @classmethod
    def tearDownClass(cls):
        # Clean up any remaining files in the S3 bucket
        s3_delete_file(file_path="testfile.txt")
        super().tearDownClass()
