"""_____________________________________________________________________

:PROJECT: lara-django

*django*

:details: django 
   core/management/base.py
   https://stackoverflow.com/questions/31838882/check-for-pending-django-migrations/49310733

:authors: mark doerr (mark@uni-greifswald.de)

:date: (creation)          20210416

.. note:: -
.. todo:: -
________________________________________________________________________

**Copyright**:
  This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
  INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

  For further Information see LICENSE file that comes with this distribution.
________________________________________________________________________
"""

__version__ = "0.0.1"

import os
import logging

from django.core.management.base import BaseCommand, CommandError
from django.core.management import call_command
# ~ from django.core.management.commands import loaddata
from django.core.exceptions import ImproperlyConfigured
from django.core.management.color import color_style, no_style
from django.db import DEFAULT_DB_ALIAS, connections
from django.conf import settings


class Command(BaseCommand):
    """see https://docs.djangoproject.com/en/1.9/howto/custom-management-commands/ for more details
       using now new argparse mechanism of django > 1.8
    """
    # logging.basicConfig(format='%(levelname)s| %(module)s.%(funcName)s:%(message)s',
    #                    level=logging.DEBUG)  # level=logging.ERROR

    help = 'show migration information.'

    def add_arguments(self, parser):
        """ command line arguments s. https://docs.python.org/2/library/argparse.html#module-argparse """

        parser.add_argument('-n', '--num-pending-migrations',
                            action='store_true',
                            help='number of pending migrations')

        parser.add_argument('-l', '--list-pending-migrations',
                            action='store_true',
                            help='list of pending migrations')

        parser.add_argument('-c', '--check-migrations',
                            action='store_true',
                            help='check  migrations')
        parser.add_argument(
            "--database",
            default=DEFAULT_DB_ALIAS,
            help=(
                'Nominates a database to introspect. Defaults to using the "default" '
                "database."
            ),
        )
        
        parser.add_argument('-t', '--check-db-table',
                            action='store',
                            help='check for table in database')

    def handle(self, *args, **options):
        """Dispatcher based on commandline arguments/options"""

        if options['num_pending_migrations']:
            self.num_migrations()
        elif options['list_pending_migrations']:
            self.list_migrations()
        elif options['check_migrations']:
            self.check_migrations()
        elif options['check_db_table']:
            self.check_db_table(options)

    def num_migrations(self):
        """Initialises the LARA database
           :param options:
        """
        from django.db.migrations.executor import MigrationExecutor
        try:
            executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
        except ImproperlyConfigured:
            # No databases are configured (or the dummy one)
            return

        plan = executor.migration_plan(executor.loader.graph.leaf_nodes())
        if plan:
            print(len(plan))

    def list_migrations(self):
        """
        Print a warning if the set of migrations on disk don't match the
        migrations in the database.
        """
        from django.db.migrations.executor import MigrationExecutor
        try:
            executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
        except ImproperlyConfigured:
            # No databases are configured (or the dummy one)
            return

        plan = executor.migration_plan(executor.loader.graph.leaf_nodes())
        if plan:
            apps_waiting_migration = sorted(
                {migration.app_label for migration, backwards in plan})
            print(", ".join(apps_waiting_migration))

    def check_migrations(self):
        """
        Print a warning if the set of migrations on disk don't match the
        migrations in the database.
        """
        from django.db.migrations.executor import MigrationExecutor
        try:
            executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
        except ImproperlyConfigured:
            # No databases are configured (or the dummy one)
            return

        plan = executor.migration_plan(executor.loader.graph.leaf_nodes())
        if plan:
            apps_waiting_migration = sorted(
                {migration.app_label for migration, backwards in plan})
            self.stdout.write(
                self.style.NOTICE(
                    "\nYou have %(unapplied_migration_count)s unapplied migration(s). "
                    "Your project may not work properly until you apply the "
                    "migrations for app(s): %(apps_waiting_migration)s." % {
                        "unapplied_migration_count": len(plan),
                        "apps_waiting_migration": ", ".join(apps_waiting_migration),
                    }
                )
            )
            self.stdout.write(self.style.NOTICE(
                "Run 'python manage.py migrate' to apply them."))
            
    def check_db_table(self, options ):
        connection = connections[options["database"]]
        table_name = options["check_db_table"]
        return table_name in connection.introspection.table_names()
