# (c) cavaliba.com - test_datatask_model

import uuid

from django.test import TestCase
from django.utils import timezone

from app_data.models import DataTask


class TestDataTaskModel(TestCase):
    def test_create_defaults(self):
        dt = DataTask.objects.create(name="test task", owner_id="user1")
        self.assertIsNotNone(dt.pk)
        self.assertIsNotNone(dt.handle)
        self.assertEqual(dt.state, "QUEUED")
        self.assertEqual(dt.owner_type, "user")
        self.assertEqual(dt.owner_id, "user1")
        self.assertIsNone(dt.singleton)
        self.assertIsNone(dt.params)
        self.assertIsNone(dt.progress)
        self.assertIsNone(dt.output)
        self.assertIsNone(dt.attachment)
        self.assertIsNotNone(dt.created_at)
        self.assertIsNone(dt.finished_at)

    def test_handle_is_uuid(self):
        dt = DataTask.objects.create(name="test", owner_id="u1")
        self.assertIsInstance(dt.handle, uuid.UUID)

    def test_handle_unique(self):
        handle = uuid.uuid4()
        DataTask.objects.create(name="t1", owner_id="u1", handle=handle)
        from django.db import IntegrityError

        with self.assertRaises(IntegrityError):
            DataTask.objects.create(name="t2", owner_id="u1", handle=handle)

    def test_state_transitions(self):
        dt = DataTask.objects.create(name="test", owner_id="u1")
        self.assertEqual(dt.state, "QUEUED")
        dt.state = "RUNNING"
        dt.save()
        dt.refresh_from_db()
        self.assertEqual(dt.state, "RUNNING")
        dt.state = "DONE"
        dt.finished_at = timezone.now()
        dt.save()
        dt.refresh_from_db()
        self.assertEqual(dt.state, "DONE")
        self.assertIsNotNone(dt.finished_at)

    def test_state_failed(self):
        dt = DataTask.objects.create(name="test", owner_id="u1")
        dt.state = "FAILED"
        dt.finished_at = timezone.now()
        dt.save()
        dt.refresh_from_db()
        self.assertEqual(dt.state, "FAILED")

    def test_state_aborted(self):
        dt = DataTask.objects.create(name="test", owner_id="u1")
        dt.state = "ABORTED"
        dt.finished_at = timezone.now()
        dt.save()
        dt.refresh_from_db()
        self.assertEqual(dt.state, "ABORTED")

    def test_singleton_field(self):
        dt = DataTask.objects.create(name="test", owner_id="u1", singleton="eav_refresh")
        dt.refresh_from_db()
        self.assertEqual(dt.singleton, "eav_refresh")

    def test_params_json(self):
        params = {"schema": "myschema", "dryrun": True}
        dt = DataTask.objects.create(name="test", owner_id="u1", params=params)
        dt.refresh_from_db()
        self.assertEqual(dt.params["schema"], "myschema")
        self.assertEqual(dt.params["dryrun"], True)

    def test_progress_json(self):
        dt = DataTask.objects.create(name="test", owner_id="u1")
        dt.progress = {"percent": 42, "count": 42, "total": 100, "errors": 0, "message": "ok"}
        dt.save()
        dt.refresh_from_db()
        self.assertEqual(dt.progress["percent"], 42)

    def test_attachment_json(self):
        dt = DataTask.objects.create(name="test", owner_id="u1")
        dt.attachment = {"type": "file", "value": "/tmp/result.csv"}
        dt.save()
        dt.refresh_from_db()
        self.assertEqual(dt.attachment["type"], "file")
        self.assertEqual(dt.attachment["value"], "/tmp/result.csv")

    def test_owner_type_api(self):
        dt = DataTask.objects.create(name="test", owner_id="apikey1", owner_type="api")
        dt.refresh_from_db()
        self.assertEqual(dt.owner_type, "api")

    def test_str(self):
        dt = DataTask.objects.create(name="mytask", owner_id="u1")
        s = str(dt)
        self.assertIn("mytask", s)
        self.assertIn("QUEUED", s)
