# -*- coding: utf-8 -*-

from flexmock import flexmock, flexmock_teardown
from .. import EloquentTestCase
from eloquent.migrations import DatabaseMigrationRepository
from eloquent import DatabaseManager
from eloquent.query import QueryBuilder
from eloquent.connections import Connection
from eloquent.schema import SchemaBuilder


class DatabaseMigrationRepositoryTestCase(EloquentTestCase):

    def tearDown(self):
        flexmock_teardown()

    def test_get_ran_migrations_list_migrations_by_package(self):
        repo = self.get_repository()
        connection = flexmock(Connection(None))
        query = flexmock(QueryBuilder(connection, None, None))
        repo.get_connection_resolver().should_receive('connection').with_args(None).and_return(connection)
        repo.get_connection().should_receive('table').once().with_args('migrations').and_return(query)
        query.should_receive('lists').once().with_args('migration').and_return('bar')

        self.assertEqual('bar', repo.get_ran())

    def test_get_last_migrations(self):
        resolver_mock = flexmock(DatabaseManager)
        resolver_mock.should_receive('connection').and_return(None)
        resolver = flexmock(resolver_mock({}))
        repo = flexmock(DatabaseMigrationRepository(resolver, 'migrations'))
        connection = flexmock(Connection(None))
        query = flexmock(QueryBuilder(connection, None, None))
        repo.should_receive('get_last_batch_number').and_return(1)
        repo.get_connection_resolver().should_receive('connection').with_args(None).and_return(connection)
        repo.get_connection().should_receive('table').once().with_args('migrations').and_return(query)
        query.should_receive('where').once().with_args('batch', 1).and_return(query)
        query.should_receive('order_by').once().with_args('migration', 'desc').and_return(query)
        query.should_receive('get').once().and_return('foo')

        self.assertEqual('foo', repo.get_last())

    def test_log_inserts_record_into_migration_table(self):
        repo = self.get_repository()
        connection = flexmock(Connection(None))
        query = flexmock(QueryBuilder(connection, None, None))
        repo.get_connection_resolver().should_receive('connection').with_args(None).and_return(connection)
        repo.get_connection().should_receive('table').once().with_args('migrations').and_return(query)
        query.should_receive('insert').once().with_args(migration='bar', batch=1)

        repo.log('bar', 1)

    def test_delete_removes_migration_from_table(self):
        repo = self.get_repository()
        connection = flexmock(Connection(None))
        query = flexmock(QueryBuilder(connection, None, None))
        repo.get_connection_resolver().should_receive('connection').with_args(None).and_return(connection)
        repo.get_connection().should_receive('table').once().with_args('migrations').and_return(query)
        query.should_receive('where').once().with_args('migration', 'foo').and_return(query)
        query.should_receive('delete').once()

        class Migration(object):

            migration = 'foo'

            def __getitem__(self, item):
                return self.migration

        repo.delete(Migration())

    def test_get_next_batch_number_returns_last_batch_number_plus_one(self):
        resolver_mock = flexmock(DatabaseManager)
        resolver_mock.should_receive('connection').and_return(None)
        resolver = flexmock(resolver_mock({}))
        repo = flexmock(DatabaseMigrationRepository(resolver, 'migrations'))
        repo.should_receive('get_last_batch_number').and_return(1)

        self.assertEqual(2, repo.get_next_batch_number())

    def test_get_last_batch_number_returns_max_batch(self):
        repo = self.get_repository()
        connection = flexmock(Connection(None))
        query = flexmock(QueryBuilder(connection, None, None))
        repo.get_connection_resolver().should_receive('connection').with_args(None).and_return(connection)
        repo.get_connection().should_receive('table').once().with_args('migrations').and_return(query)
        query.should_receive('max').and_return(1)

        self.assertEqual(1, repo.get_last_batch_number())

    def get_repository(self):
        resolver = flexmock(DatabaseManager)
        resolver.should_receive('connection').and_return(None)
        return DatabaseMigrationRepository(flexmock(resolver({})), 'migrations')
