'''
Created on Jun 7, 2011

@author: ymh
'''

from django.core.management.base import NoArgsCommand
from django.core.management.color import no_style
from haystack.constants import DJANGO_ID
from haystack.query import SearchQuerySet
from hdabo.models import Datasheet
import math
import sys
from optparse import make_option
from django.db import transaction


class Command(NoArgsCommand):
    '''
    Command to calculate the order of tags based on indexation
    recalculate all tags. Will ask for confirmation
    '''

    args = ''
    options = '-f : force '
    help = "calculate the order of tags based on indexation recalculate all tags. Will ask for confirmation"
    
    option_list = NoArgsCommand.option_list + (
        make_option('-f', '--force',
            action='store_true',
            dest='force',
            default=False,
            help='force reordering of all datasheets'),
        )


    def show_progress(self, current_line, total_line, width):

        percent = (float(current_line) / float(total_line)) * 100.0

        marks = math.floor(width * (percent / 100.0))
        spaces = math.floor(width - marks)
    
        loader = u'[' + (u'=' * int(marks)) + (u' ' * int(spaces)) + u']'
    
        sys.stdout.write(u"%s %d%% %d/%d\r" % (loader, percent, current_line, total_line)) #takes the header into account
        if percent >= 100:
            sys.stdout.write("\n")
        sys.stdout.flush()


    def handle_noargs(self, **options):
        
        self.style = no_style()
        
        interactive = options.get('interactive', True)
        force = options.get('force', True)
        
        if interactive:
            confirm = raw_input("""You have requested to recalculate the index order of all the tags.
This will process all the tags in %s datasheets. Are you sure you want to do this ?
    Type 'yes' to continue, or 'no' to cancel: """ % ("all" if force else "not validated"))
        else:
            confirm = 'yes'
            
        if confirm != "yes":
            print "Tag reordering cancelled"
            return

        if force:
            queryset = Datasheet.objects.all()
        else:
            queryset = Datasheet.objects.filter(validated=False, manual_order=False)
        total = queryset.count()
        
        transaction.commit_unless_managed()
        transaction.enter_transaction_management()
        transaction.managed(True)

        try:
            for i, ds in enumerate(queryset):
                self.show_progress(i + 1, total, 60)
                ts_list = []
                for ts in ds.taggedsheet_set.all():
                    kwargs = {DJANGO_ID + "__exact": unicode(ds.pk)}
                    results = SearchQuerySet().filter(title=ts.tag.label).filter_or(description=ts.tag.label).filter(**kwargs)
                    if len(results) > 0:
                        ts.index_note = results[0].score
                        ts.save()
                    ts_list.append(ts)
                ts_list.sort(key=lambda t: (-t.index_note, t.order))
                for i, ts in enumerate(ts_list):
                    ts.order = i + 1
                    ts.save()
                if ds.manual_order:
                    ds.manual_order = False
                    ds.save()
                transaction.commit()
        except:
            transaction.rollback()
            raise
        finally:
            transaction.leave_transaction_management()
            
        
