import unittest

from mygrations.formats.mysql.db_reader.database import database as database_reader
from mygrations.drivers.mysqldb.mysqldb import mysqldb
from tests.mocks.db.mysql.db_structure import db_structure
from mygrations.formats.mysql.mygrations.row_mygration import row_mygration

class test_mygrate_rows_simple( unittest.TestCase ):

    def _get_tables( self ):

        return {
            'logs': """
                CREATE TABLE `logs` (
                    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
                    `message` TEXT NOT NULL,
                    `traceback` text,
                    PRIMARY KEY (`id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8;""",
            'more_logs': """
                CREATE TABLE `more_logs` (
                    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
                    `more_messages` TEXT NOT NULL,
                    `traceback` text,
                    PRIMARY KEY (`id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"""
        }

    def test_add_rows( self ):

        # I could also just create the database and add rows but I feel like doing this
        tables = self._get_tables()
        rows = {
            'logs': (
                { 'id': 1, 'message': 'hey', 'traceback': 'never' },
                { 'id': 2, 'message': 'sup', 'traceback': 'forever' }
            )
        }

        database = database_reader( mysqldb( db_structure( tables, rows ) ) )
        database.read_rows( 'logs' )

        operations = [ str( op ) for op in row_mygration( database ).operations ]
        self.assertEquals( 2, len( operations ) )
        self.assertEquals( "INSERT INTO `logs` (`id`, `message`, `traceback`) VALUES ('1', 'hey', 'never');", operations[0] )
        self.assertEquals( "INSERT INTO `logs` (`id`, `message`, `traceback`) VALUES ('2', 'sup', 'forever');", operations[1] )

    def test_modify_rows( self ):

        # I could also just create the database and add rows but I feel like doing this
        tables = self._get_tables()
        rows = {
            'logs': (
                { 'id': 1, 'message': 'hey', 'traceback': 'never' },
                { 'id': 2, 'message': 'sup', 'traceback': 'forever' }
            )
        }

        database = database_reader( mysqldb( db_structure( tables, rows ) ) )
        database.read_rows( 'logs' )

        rows_from = {
            'logs': (
                { 'id': 1, 'message': 'hey', 'traceback': 'bah' },
                { 'id': 2, 'message': 'sup', 'traceback': 'forever' }
            )
        }
        database_from = database_reader( mysqldb( db_structure( tables, rows_from ) ) )
        database_from.read_rows( 'logs' )

        operations = [ str( op ) for op in row_mygration( database, database_from ).operations ]
        self.assertEquals( 1, len( operations ) )
        self.assertEquals( "UPDATE `logs` SET `message`='hey', `traceback`='never' WHERE id=1;", operations[0] )

    def test_delete_rows( self ):

        # I could also just create the database and add rows but I feel like doing this
        tables = self._get_tables()
        rows = {
            'logs': (
                { 'id': 2, 'message': 'sup', 'traceback': 'forever' },
            )
        }

        database = database_reader( mysqldb( db_structure( tables, rows ) ) )
        database.read_rows( 'logs' )

        rows_from = {
            'logs': (
                { 'id': 1, 'message': 'hey', 'traceback': 'never' },
                { 'id': 2, 'message': 'sup', 'traceback': 'forever' }
            )
        }
        database_from = database_reader( mysqldb( db_structure( tables, rows_from ) ) )
        database_from.read_rows( 'logs' )

        operations = [ str( op ) for op in row_mygration( database, database_from ).operations ]
        self.assertEquals( 1, len( operations ) )
        self.assertEquals( "DELETE FROM `logs` WHERE id=1;", operations[0] )

    def test_all( self ):

        # I could also just create the database and add rows but I feel like doing this
        tables = self._get_tables()
        rows = {
            'logs': (
                { 'id': 2, 'message': 'sup', 'traceback': 'whatever' },
                { 'id': 3, 'message': 'okay', 'traceback': 'always' }
            )
        }

        database = database_reader( mysqldb( db_structure( tables, rows ) ) )
        database.read_rows( 'logs' )

        rows_from = {
            'logs': (
                { 'id': 1, 'message': 'hey', 'traceback': 'never' },
                { 'id': 2, 'message': 'sup', 'traceback': 'forever' }
            )
        }
        database_from = database_reader( mysqldb( db_structure( tables, rows_from ) ) )
        database_from.read_rows( 'logs' )

        operations = [ str( op ) for op in row_mygration( database, database_from ).operations ]
        # don't be picky about the order
        self.assertEquals( 3, len( operations ) )
        self.assertTrue( "INSERT INTO `logs` (`id`, `message`, `traceback`) VALUES ('3', 'okay', 'always');" in operations )
        self.assertTrue( "DELETE FROM `logs` WHERE id=1;" in operations )
        self.assertTrue( "UPDATE `logs` SET `message`='sup', `traceback`='whatever' WHERE id=2;" in operations )
