import os
from os.path import dirname

import pytest
from src.superannotate import AppException
from src.superannotate import SAClient
from tests.integration.base import BaseTestCase

sa = SAClient()


class TestVectorAnnotationsWithTag(BaseTestCase):
    PROJECT_NAME = "TestVectorAnnotationsWithTag"
    PROJECT_TYPE = "Vector"
    PROJECT_DESCRIPTION = "TestVectorAnnotationsWithTag"
    TEST_FOLDER_PTH = "data_set/sample_project_vector_with_tag"
    EXAMPLE_IMAGE_1 = "example_image_1.jpg"

    @property
    def folder_path(self):
        return os.path.join(dirname(dirname(__file__)), self.TEST_FOLDER_PTH)

    @property
    def classes_json_path(self):
        return f"{self.folder_path}/classes/classes.json"

    def test_vector_annotations_with_tag(self):
        sa.upload_images_from_folder_to_project(
            self.PROJECT_NAME, self.folder_path, annotation_status="InProgress"
        )
        sa.create_annotation_classes_from_classes_json(
            self.PROJECT_NAME, self.classes_json_path
        )
        sa.upload_image_annotations(
            project=self.PROJECT_NAME,
            image_name=self.EXAMPLE_IMAGE_1,
            annotation_json=f"{self.folder_path}/{self.EXAMPLE_IMAGE_1}___objects.json",
        )
        annotations = sa.get_annotations(self.PROJECT_NAME, [self.EXAMPLE_IMAGE_1])[0]
        self.assertEqual(annotations["instances"][0]["type"], "tag")
        self.assertEqual(annotations["instances"][0]["attributes"][0]["name"], "1")
        self.assertEqual(
            annotations["instances"][0]["attributes"][0]["groupName"], "g1"
        )
        sa.pin_image(self.PROJECT_NAME, self.EXAMPLE_IMAGE_1, pin=True)
        metadata = sa.get_item_metadata(
            self.PROJECT_NAME, item_name=self.EXAMPLE_IMAGE_1
        )
        assert metadata["is_pinned"] is True


class TestPinImage(BaseTestCase):
    PROJECT_NAME = "TestPinImage"
    PROJECT_TYPE = "Vector"
    PROJECT_DESCRIPTION = "TestPinImage"

    def test_pin_image_negative_name(self):
        with self.assertRaisesRegex(AppException, "Item not found."):
            sa.pin_image(self.PROJECT_NAME, "NEW NAME")


class TestVectorAnnotationsWithTagFolderUpload(BaseTestCase):
    PROJECT_NAME = "TestVectorAnnotationsWithTagFolderUpload"
    PROJECT_TYPE = "Vector"
    PROJECT_DESCRIPTION = "TestVectorAnnotationsWithTag"
    TEST_FOLDER_PTH = "data_set/sample_project_vector_with_tag"
    EXAMPLE_IMAGE_1 = "example_image_1.jpg"

    @property
    def folder_path(self):
        return os.path.join(dirname(dirname(__file__)), self.TEST_FOLDER_PTH)

    @property
    def classes_json_path(self):
        return f"{self.folder_path}/classes/classes.json"

    @pytest.mark.flaky(reruns=2)
    def test_vector_annotations_with_tag_folder_upload(self):
        sa.upload_images_from_folder_to_project(
            self.PROJECT_NAME, self.folder_path, annotation_status="InProgress"
        )
        sa.create_annotation_classes_from_classes_json(
            self.PROJECT_NAME, self.classes_json_path
        )
        sa.upload_annotations_from_folder_to_project(
            self.PROJECT_NAME, self.folder_path
        )
        annotations = sa.get_annotations(self.PROJECT_NAME, [self.EXAMPLE_IMAGE_1])[0]
        self.assertEqual(annotations["instances"][0]["type"], "tag")
        self.assertEqual(annotations["instances"][0]["attributes"][0]["name"], "1")
        self.assertEqual(
            annotations["instances"][0]["attributes"][0]["groupName"], "g1"
        )


class TestVectorAnnotationsWithTagFolderUploadPreannotation(BaseTestCase):
    PROJECT_NAME = "PreTestVectorAnnotationsWithTagFolderUpload"
    PROJECT_TYPE = "Vector"
    PROJECT_DESCRIPTION = "TestVectorAnnotationsWithTag"
    TEST_FOLDER_PTH = "data_set/sample_project_vector_with_tag"
    EXAMPLE_IMAGE_1 = "example_image_1.jpg"

    @property
    def folder_path(self):
        return os.path.join(dirname(dirname(__file__)), self.TEST_FOLDER_PTH)

    @property
    def classes_json_path(self):
        return f"{self.folder_path}/classes/classes.json"
