from __future__ import print_function
from tests.test_contract import OrloTest
from random import randrange
from orlo.orm import db
from orlo.orm import Release, Package, PackageResult, Platform
from orlo import app
from orlo.util import append_or_create_platforms
from sqlalchemy.orm import exc
import arrow
import datetime
import uuid
from six import string_types

__author__ = 'alforbes'

'''
Tests for the database / orm layer
'''


class OrloDbTest(OrloTest):
    """
    Base test class for tests that need to manipulate data without using the http API
    """

    def _create_release(self,
                        user='testuser',
                        team='test team',
                        platforms=None,
                        references=None,
                        success=True):
        """
        Create a release using internal methods

        :param user:
        :param team:
        :param platforms:
        :param references:
        :return:
        """

        if not platforms:
            platforms = ['test_platform']
        if type(platforms) is not list:
            raise AssertionError("Platforms parameter must be list")
        if not references:
            references = ['TestTicket-123']

        db_platforms = append_or_create_platforms(platforms)

        r = Release(
            platforms=db_platforms,
            user=user,
            references=references,
            team=team,
        )
        db.session.add(r)
        db.session.commit()

        return r.id

    @staticmethod
    def _create_package(release_id,
                        name='test-package',
                        version='1.2.3',
                        diff_url=None,
                        rollback=False,
                        ):
        """
        Create a package using internal methods

        :param release_id:
        :param name:
        :param version:
        :param diff_url:
        :param rollback:
        :return:
        """
        p = Package(
            release_id=release_id,
            name=name,
            version=version,
            diff_url=diff_url,
            rollback=rollback,
        )
        db.session.add(p)
        db.session.commit()

        return p.id

    @staticmethod
    def _start_package(package_id):
        """
        Start a package

        :param package_id:
        """
        package = db.session.query(Package).filter(Package.id == package_id).one()
        package.start()
        db.session.commit()

        return package.id

    @staticmethod
    def _stop_package(package_id, success=True):
        """
        Stop a package

        :param package_id:
        """
        package = db.session.query(Package).filter(Package.id == package_id).one()
        package.stop(success=success)
        db.session.commit()

    @staticmethod
    def _stop_release(release_id):
        """
        Stop a release

        :param release_id:
        """
        release = db.session.query(Release).filter(Release.id == release_id).one()
        release.stop()
        db.session.commit()

    def _create_finished_release(self, success=True):
        """
        Create a completed release using internal methods
        """

        release_id = self._create_release()
        package_id = self._create_package(release_id)

        self._start_package(package_id)
        self._stop_package(package_id, success=success)
        self._stop_release(release_id)
        db.session.commit()


class TestFields(OrloDbTest):
    def setUp(self):
        super(OrloDbTest, self).setUp()

        for r in range(0, 3):
            self._create_finished_release()

    def test_release_types(self):
        """
        Test the types returned by Release objects are OK
        """
        r = db.session.query(Release).first()
        self.assertIs(type(r.id), uuid.UUID)
        self.assertIs(hasattr(r.notes, '__iter__'), True)
        self.assertIs(hasattr(r.platforms, '__iter__'), True)
        self.assertIn(type(r.references), string_types)
        self.assertIs(type(list(r.references)), list)
        self.assertIs(type(r.stime), arrow.arrow.Arrow)
        self.assertIs(type(r.ftime), arrow.arrow.Arrow)
        self.assertIs(type(r.duration), datetime.timedelta)
        self.assertIn(type(r.team), string_types)

    def test_package_types(self):
        """
        Test the types returned by Package objects are OK
        """
        p = db.session.query(Package).first()
        x = db.session.query(Package).all()
        self.assertIs(type(p.id), uuid.UUID)
        self.assertIn(type(p.name), string_types)
        self.assertIs(type(p.stime), arrow.arrow.Arrow)
        self.assertIs(type(p.ftime), arrow.arrow.Arrow)
        self.assertIs(type(p.duration), datetime.timedelta)
        self.assertIn(type(p.status), string_types)
        self.assertIn(type(p.version), string_types)

@@ -3832,19 +3832,21 @@
 rtIs
-(typ
+Instanc
 e(r.id
-)
 , uu
@@ -3990,29 +3990,32 @@
 self.assertI
-n(typ
+sInstanc
 e(r.referenc
@@ -4016,17 +4016,16 @@
 ferences
-)
 , string
@@ -4103,28 +4103,31 @@
 elf.assertIs
-(typ
+Instanc
 e(r.stime), 
@@ -4119,25 +4119,24 @@
 ance(r.stime
-)
 , arrow.arro
@@ -4161,28 +4161,31 @@
 elf.assertIs
-(typ
+Instanc
 e(r.ftime), 
@@ -4177,25 +4177,24 @@
 ance(r.ftime
-)
 , arrow.arro
@@ -4223,20 +4223,23 @@
 assertIs
-(typ
+Instanc
 e(r.dura
@@ -4234,33 +4234,32 @@
 tance(r.duration
-)
 , datetime.timed
@@ -4288,21 +4288,24 @@
 ertI
-n(typ
+sInstanc
 e(r.team
 ), s
@@ -4300,17 +4300,16 @@
 e(r.team
-)
 , string
@@ -4548,19 +4548,21 @@
 rtIs
-(typ
+Instanc
 e(p.id
-)
 , uu
@@ -4594,21 +4594,24 @@
 ertI
-n(typ
+sInstanc
 e(p.name
 ), s
@@ -4606,17 +4606,16 @@
 e(p.name
-)
 , string
@@ -4639,28 +4639,31 @@
 elf.assertIs
-(typ
+Instanc
 e(p.stime), 
@@ -4655,25 +4655,24 @@
 ance(p.stime
-)
 , arrow.arro
@@ -4697,28 +4697,31 @@
 elf.assertIs
-(typ
+Instanc
 e(p.ftime), 
@@ -4717,17 +4717,16 @@
 (p.ftime
-)
 , arrow.
@@ -4759,20 +4759,23 @@
 assertIs
-(typ
+Instanc
 e(p.dura
@@ -4778,17 +4778,16 @@
 duration
-)
 , dateti
@@ -4816,29 +4816,32 @@
 self.assertI
-n(typ
+sInstanc
 e(p.status),
@@ -4838,17 +4838,16 @@
 p.status
-)
 , string
@@ -4878,13 +4878,16 @@
 ertI
-n(typ
+sInstanc
 e(p.
@@ -4893,17 +4893,16 @@
 .version
-)
 , string

Fix for python2 again