from tests.opentera.db.models.BaseModelsTest import BaseModelsTest
from sqlalchemy import exc
from opentera.db.models.TeraServiceRole import TeraServiceRole


class TeraServiceRoleTest(BaseModelsTest):

    def test_nullable_args(self):
        with self._flask_app.app_context():
            new_service_role = TeraServiceRole()
            new_service_role.id_service = 1
            new_service_role.service_role_name = None

            self.db.session.add(new_service_role)
            self.assertRaises(exc.IntegrityError, self.db.session.commit)
            self.db.session.rollback()

            new_service_role = TeraServiceRole()
            new_service_role.id_service = None
            new_service_role.service_role_name = 'Service_role_name'

            self.db.session.add(new_service_role)
            self.assertRaises(exc.IntegrityError, self.db.session.commit)

    def test_relationships(self):
        with self._flask_app.app_context():
            new_service_role = TeraServiceRole()
            new_service_role.id_service = 10
            new_service_role.service_role_name = 'Role Name'
            self.db.session.add(new_service_role)
            self.assertRaises(exc.IntegrityError, self.db.session.commit)

    def test_service_role_to_json(self):
        with self._flask_app.app_context():
            new_service_role = TeraServiceRole()
            new_service_role.id_service = 1
            new_service_role.id_project = 1
            new_service_role.id_site = 1
            new_service_role.service_role_name = 'Role Name'
            self.db.session.add(new_service_role)
            self.db.session.commit()
            json_data = new_service_role.to_json()
            json_data_minimal = new_service_role.to_json(minimal=True)
            self._check_json(new_service_role, json_data)
            self._check_json(new_service_role, json_data_minimal, minimal=True)

    def _check_json(self, service_role, json_data, minimal=False):
        self.assertEqual(service_role.id_service, json_data['id_service'])
        self.assertEqual(service_role.id_project, json_data['id_project'])
        self.assertEqual(service_role.id_site, json_data['id_site'])
        self.assertEqual(service_role.service_role_name, json_data['service_role_name'])
        if minimal:
            pass

    def test_get_service_role(self):
        with self._flask_app.app_context():
            new_service_role = TeraServiceRole()
            new_service_role.id_service = 1
            new_service_role.id_project = 1
            new_service_role.id_site = 1
            new_service_role.service_role_name = 'Role Name'
            self.db.session.add(new_service_role)
            self.db.session.commit()
            same_service_role = TeraServiceRole.get_service_roles(service_id=new_service_role.id_service)
            for service_role in same_service_role:
                self.assertEqual(service_role.service_role_service.service_name, 'OpenTera Server')
            self.assertEqual(same_service_role[-1], new_service_role)

    def test_get_service_roles_for_site(self):
        with self._flask_app.app_context():
            new_service_role = TeraServiceRole()
            self.db.session.rollback()
            new_service_role.id_service = 1
            new_service_role.id_project = 1
            new_service_role.id_site = 1
            new_service_role.service_role_name = 'Role Name'
            self.db.session.add(new_service_role)
            self.db.session.commit()
            same_service_role = TeraServiceRole.get_service_roles_for_site(service_id=new_service_role.id_service,
                                                                           site_id=new_service_role.id_site)
            for service_role in same_service_role:
                self.assertEqual(service_role.service_role_service.service_name, 'OpenTera Server')
                self.assertEqual(service_role.id_site, new_service_role.id_site)
            self.assertEqual(same_service_role[-1], new_service_role)

    def test_get_specific_service_role_for_site(self):
        with self._flask_app.app_context():
            new_service_role = TeraServiceRole()
            new_service_role.id_service = 1
            new_service_role.id_project = 1
            new_service_role.id_site = 1
            new_service_role.service_role_name = 'Role Name'
            self.db.session.add(new_service_role)
            self.db.session.commit()
            same_service_role = TeraServiceRole.get_service_role_by_name(service_id=new_service_role.id_service,
                                                                         site_id=new_service_role.id_site,
                                                                         rolename=new_service_role.service_role_name)
            self.assertEqual(same_service_role.service_role_name, new_service_role.service_role_name)
            # the BaseModelstest is changing the same_service_role.id_service_role
            # when the class is the but not the test alone

    def test_get_service_roles_for_project(self):
        with self._flask_app.app_context():
            new_service_role = TeraServiceRole()
            new_service_role.id_service = 1
            new_service_role.id_project = 1
            new_service_role.id_site = 1
            new_service_role.service_role_name = 'Role Name'
            self.db.session.add(new_service_role)
            self.db.session.commit()
            same_service_role = TeraServiceRole.get_service_roles_for_project(service_id=new_service_role.id_service,
                                                                              project_id=new_service_role.id_project)
            for service_role in same_service_role:
                self.assertEqual(service_role.service_role_service.service_name, 'OpenTera Server')
            self.assertEqual(same_service_role[-1], new_service_role)

    def test_get_specific_service_role_for_project(self):
        with self._flask_app.app_context():
            new_service_role = TeraServiceRole()
            new_service_role.id_service = 1
            new_service_role.id_project = 1
            new_service_role.id_site = 1
            new_service_role.service_role_name = 'Role Name'
            self.db.session.add(new_service_role)
            self.db.session.commit()
            same_service_role = TeraServiceRole.get_service_role_by_name(
                service_id=new_service_role.id_service, project_id=new_service_role.id_project,
                rolename=new_service_role.service_role_name)
            self.assertEqual(same_service_role.service_role_name, new_service_role.service_role_name)

    def test_get_service_role_by_id(self):
        with self._flask_app.app_context():
            new_service_role = TeraServiceRole()
            new_service_role.id_service = 1
            new_service_role.id_project = 1
            new_service_role.id_site = 1
            new_service_role.service_role_name = 'Role Name'
            self.db.session.add(new_service_role)
            self.db.session.commit()
            same_service_role = TeraServiceRole.get_service_role_by_id(role_id=new_service_role.id_service_role)
            self.assertEqual(same_service_role, new_service_role)

    @staticmethod
    def new_test_service_role(id_service: int, role_name: str, id_site: int | None = None) -> TeraServiceRole:
        service_role = TeraServiceRole()
        service_role.id_service = id_service
        service_role.service_role_name = role_name
        if id_site:
            service_role.id_site = id_site
        TeraServiceRole.insert(service_role)
        return service_role
