# -*- coding: utf-8 -*-
'''
Created on Jun 17, 2011

@author: ymh

command to import tag popularity

'''

from django.core.management.base import BaseCommand, CommandError
from hdabo.models import Tag
from hdabo.utils import normalize
from optparse import make_option
import csv
import math
import sys


class Command(BaseCommand):
    '''
    Command to import csvfile
    '''
    args = '<path_to_csv_file path_to_csv_file ...>'
    options = '[--ignore-existing] [--lines] [--encoding]'
    help = """Import of a tag popularity file for hdabo
Options:
    --ignore-existing : ignore existing datasheets
    --lines : max number of lines to load (for each file). 0 means all.
    --encoding : files encoding. default to latin-1"""
    
    option_list = BaseCommand.option_list + (
        make_option('--encoding',
            action='store',
            type='string',
            dest='encoding',
            default="latin-1",
            help='fix the file encoding. default to latin-1'),
        make_option('--delimiter',
            action='store',
            type='string',
            dest='delimiter',
            default=";",
            help='csv file delimiter'),
        make_option('--dialect',
            action='store',
            type='string',
            dest='dialect',
            default="excel",
            help='csv dialect'),
        make_option('--fieldnames',
            action='store',
            type='string',
            dest='fieldnames',
            default="label,popularity",
            help='fields list (comma separated)'),
        make_option('--lines',
            action='store',
            type='int',
            dest='lines',
            default=0,
            help='Number of lines to read. 0 means all.'),
        make_option('--preserve',
            action='store_true',
            dest='preserve',
            default=False,
            help='preserve'),
                                             
        
        )
    
    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 = '[' + ('=' * int(marks)) + (' ' * int(spaces)) + ']'
    
        sys.stdout.write("%s %d%% %d/%d\r" % (loader, percent, current_line - 1, total_line - 1)) #takes the header into account
        if percent >= 100:
            sys.stdout.write("\n")
        sys.stdout.flush()

    def handle(self, *args, **options):
        
        if len(args) == 0:
            raise CommandError("Give one csv file to import")
        elif len(args) > 1:
            raise CommandError("Only one file can be imported")
        
        self.encoding = options.get('encoding', "latin-1")
        lines = options.get('lines', 0)
        fieldnames = options.get('fieldnames', "label,popularity")

        csv_path = args[0]
        
        print("Processing %s " % (csv_path))
        
        with open(csv_path, 'rU') as csv_file:
            # get the number of lines if necessary
            if not lines:
                for i, l in enumerate(csv_file): #@UnusedVariable
                    pass                        
                total_line = i + 1
                if fieldnames:
                    total_line = total_line + 1
                csv_file.seek(0)
            else:
                total_line = lines + 1

            delimiter = options.get('delimiter', ";")
            if delimiter == "TAB" or delimiter == "\\t":
                delimiter = '\t'
            dr_kwargs = {'delimiter':delimiter}
            if  fieldnames is not None:
                dr_kwargs['fieldnames'] = [f.strip() for f in fieldnames.split(",")]
            dialect = options.get('dialect', "excel")
            if dialect is not None:
                dr_kwargs['dialect'] = dialect
               
            if not options.get('preserve',False):
                Tag.objects.update(popularity=0)
            reader = csv.DictReader(csv_file, **dr_kwargs)

            for j, row in enumerate(reader):
                if lines and j >= lines:
                    break
                line_num = reader.line_num if fieldnames is None else reader.line_num + 1
                self.show_progress(line_num, total_line, 60)
                def safe_decode(val, encoding):
                    if val:
                        return val.decode(encoding)
                    else:
                        return val
                                            
                row = dict([(safe_decode(key, self.encoding), safe_decode(value, self.encoding)) for key, value in row.items()])
                
                label = normalize(row['label'].strip())
                popularity_str = row['popularity']
                
                if not label or not popularity_str:
                    continue
                
                
                for tag in Tag.objects.filter(normalized_label=label, popularity=0):
                    tag.popularity = int(row['popularity'])
                    tag.save()
