# coding: utf-8

"""
    LEIA RESTful API for AI

    Leia API  # noqa: E501

    The version of the OpenAPI document: 1.0.0
    Contact: contact@leia.io
    Generated by: https://openapi-generator.tech
"""

from __future__ import absolute_import

import os
import unittest
import time

from leiaapi.generated import Statuses, TransformTypes, ApiClient, Configuration

import leiaapi.generated
from leiaapi.generated.api.application_api import ApplicationApi  # noqa: E501
from leiaapi.generated.exceptions import NotFoundException
from leiaapi.generated.models import LoginBody


class TestApplicationApi(unittest.TestCase):
    """ApplicationApi unit test stubs"""

    def setUp(self):
        self.client = ApiClient(Configuration(host="https://dev.leia.id360docaposte.com/leia/1.0.0"))
        self.api = leiaapi.generated.api.ApplicationApi(self.client)  # noqa: E501
        self.model_api = leiaapi.generated.api.ModelApi(self.client)  # noqa: E501
        self.model_admin_api = leiaapi.generated.api.ModelAdminApi(self.client)  # noqa: E501
        self.document_api = leiaapi.generated.api.DocumentApi(self.client)
        self.job_api = leiaapi.generated.api.JobApi(self.client)
        self.application_admin_api = leiaapi.generated.api.ApplicationAdminApi(self.client)

    def tearDown(self):
        pass

    def test_login_application_post(self):
        """Test case for login_application_post

        Logs into Leia API  # noqa: E501
        """
        print(f"The test will be done against the dev environment({self.client.configuration._base_path})")
        api_key = os.environ.get("LEIA_API_KEY", None)
        self.assertIsNotNone(api_key, msg="Please set the environment variable LEIA_API_KEY to your api key")
        login_token = self.api.login_application_post(LoginBody(api_key=api_key))
        token = login_token.token
        self.assertIsNotNone(token)
        app = self.api.who_am_i(token=str(token))
        self.assertIsNotNone(app.application_type)
        self.assertIsNotNone(app.creation_time)
        print("Login OK")


        new_doc = self.document_api.create_document(token, "test-sdk.txt", "test sdk 123".encode("UTF8"), ttl=600, tags=["test-sdk"])
        self.assertIsNotNone(new_doc.id)
        print("Create document OK")

        docs = self.document_api.get_documents(token)
        self.assertGreater(len(docs), 0)
        print("Get documents 1 OK")

        docs = self.document_api.get_documents(token, document_id=new_doc.id)
        self.assertEqual(len(docs), 1)
        print("Get documents 2 OK")

        docs_2 = self.document_api.get_documents(token,
                                                 document_id=new_doc.id,
                                                 filename=new_doc.filename,
                                                 extension=new_doc.extension,
                                                 mime_type=new_doc.mime_type,
                                                 original_id=new_doc.original_id,
                                                 tags=new_doc.tags,
                                                 # This does not work because the datetime serailizer is not compatible
                                                 # created_before=docs[0].creation_time + relativedelta(hours=1),
                                                 # created_after=docs[0].creation_time - relativedelta(hours=1),
                                                 sort="filename",
                                                 offset=0,
                                                 limit=1)
        self.assertGreater(len(docs), 0)
        self.assertEqual(docs_2[0], docs[0])
        print("Get documents 3 OK")

        doc = self.document_api.get_document(token, docs[0].id)
        self.assertEqual(doc, docs[0])
        print("Get document OK")

        docs_zip = self.document_api.get_documents_zip(token,
                                                       document_id=new_doc.id,
                                                       filename=new_doc.filename,
                                                       extension=new_doc.extension,
                                                       mime_type=new_doc.mime_type,
                                                       original_id=new_doc.original_id,
                                                       tags=new_doc.tags,
                                                       # created_before=docs[0].creation_time + relativedelta(hours=1),
                                                       # created_after=docs[0].creation_time - relativedelta(hours=1)
                                                       )
        self.assertGreater(len(docs_zip), 0)
        self.assertEqual(docs_zip[0], 0x50)
        self.assertEqual(docs_zip[1], 0x4B)
        print("Get documents ZIP OK")


        data = self.document_api.get_document_contents(token, new_doc.id)
        self.assertEqual(data, "test sdk 123".encode("UTF8"))
        print("Get document content OK")

        apps = self.application_admin_api.admin_get_applications(token)
        self.assertGreater(len(apps), 0)
        print("Get applications OK")

        models = self.model_api.get_models(token)
        model = min(models, key= lambda x: x.size)
        self.assertGreater(len(models), 0)
        print("Get models OK")

        model_data = self.model_admin_api.admin_get_model_contents(token, model.application_id, model.id)
        self.assertEqual(model_data[0], 0x50)
        self.assertEqual(model_data[1], 0x4B)
        print("Get model content OK")

        job = self.model_api.apply_model_async(token, model.id, [new_doc.id], block_processing=True)
        print("Apply model OK")
        self.job_api.start_job(token, job.id)
        while job.status not in [Statuses.FAILED, Statuses.PROCESSED]:
            job = self.job_api.get_job(token, job.id)
            time.sleep(1)
        self.assertIn(job.status, [Statuses.FAILED, Statuses.PROCESSED])
        print("Apply model start OK")

        job = self.document_api.transform_document_async(token, [new_doc.id, new_doc.id], TransformTypes.MERGE, block_processing=True)
        print("Transform doc MERGE OK")
        self.job_api.start_job(token, job.id)
        while job.status not in [Statuses.FAILED, Statuses.PROCESSED]:
            job = self.job_api.get_job(token, job.id)
            time.sleep(1)
        self.assertIn(job.status, [Statuses.FAILED, Statuses.PROCESSED])
        print("Transform doc MERGE start OK")

        docs_pdf = self.document_api.get_documents(token,
                                                 mime_type="application/pdf",
                                                 limit=1)
        self.assertGreater(len(docs_pdf), 0)
        print("Get document pdf OK")


        job = self.document_api.transform_document_async(token, [docs_pdf[0].id], TransformTypes.IMAGE, block_processing=True)
        print("Transform doc IMAGE start OK")
        self.job_api.start_job(token, job.id)
        while job.status not in [Statuses.FAILED, Statuses.PROCESSED]:
            job = self.job_api.get_job(token, job.id)
            time.sleep(1)
        self.assertIn(job.status, [Statuses.FAILED, Statuses.PROCESSED])
        print("Transform doc IMAGE OK")


        job = self.document_api.transform_document_async(token, job.document_ids, TransformTypes.TEXT, block_processing=True, execute_after_id=job.id)
        print("Transform doc TEXT start OK")
        self.job_api.start_job(token, job.id)
        while job.status not in [Statuses.FAILED, Statuses.PROCESSED]:
            job = self.job_api.get_job(token, job.id)
            time.sleep(1)
        self.assertIn(job.status, [Statuses.FAILED, Statuses.PROCESSED])
        print("Transform doc TEXT OK")

        self.document_api.delete_document(token, new_doc.id)
        print("Delete doc OK")
        self.assertRaises(NotFoundException, self.document_api.get_document, token, document_id=new_doc.id)
        print("Get deleted doc OK")

        self.api.logout_application(token=str(token))
        print("logout OK")


if __name__ == '__main__':
    unittest.main()
