# -*- coding: utf-8 -*-
'''
Created on Jan 25, 2012

@author: ymh
'''

from django.core.management.base import BaseCommand, CommandError
from django.db.models import Q
from hdabo import utils
from hdabo.models import Tag
from optparse import make_option
import csv
import cStringIO
import codecs

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)

class Command(BaseCommand):
    '''
    Command to export tags
    '''
    args = '<path_to_name_base_csv_file>'
    options = '[-c|--category filter by category name] [-e|--encoding csv file encoding]'
    help = """export csv files for hdabo
Options:
    -c, --category : filter by category
    --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("-c","--category",
            action='append',
            type='string',
            dest='categories',
            default=[],
            help='filter tag by category (or)'),
        make_option("-e","--encoding",
            action='store',
            type='string',
            dest='encoding',
            default="utf-8",
            help='file encoding, default utf-8'),
        make_option("-f","--force",
            action='store_true',
            dest='force',
            default=False,
            help='force file overwrite'),
        )
        
    def handle(self, *args, **options):
        
        if len(args) == 0 or not args[0]:
            raise CommandError("Gives at last one csv file to export")

        self.encoding = options.get("encoding", "utf-8")
        self.categories = options.get("categories", [])
        self.force = options.get("force", False)
        self.base_path = args[0].strip()
        self.interactive = options.get("interactive",True)
        
        files_path = {
            "visible" : { 'path':self.base_path + "_visible.txt",},
            "hidden" : { 'path':self.base_path + "_hidden.txt",},
            "infobox" : { 'path':self.base_path + "_infobox.txt",},
        }
        
        try:
            for filedef in files_path.values():
                try:
                    filedef['file'] = open(filedef['path'],'r')
                    if (not self.force) and self.interactive:
                        print filedef['path']
                        resp = raw_input("export file already exists. override ? type yes to continue : ")
                        if resp is not None and (resp.lower() == "yes" or resp.lower() == "y"):
                            self.force = True
                            # clear file
                        else:
                            return "error"
                    elif not self.interactive and not self.force:
                        print "Export file %s already exists. Exit." % (filedef['path'])
                        return "error"

                    filedef['file'].close()
                    filedef['file'] = open(filedef['path'],'w')
                except IOError:
                    filedef['file'] = open(filedef['path'],'w')
                
                filedef['csv'] = UnicodeWriter(filedef['file'], doublequote=False, escapechar="\\", encoding=self.encoding)
                
            queryset = Tag.objects.exclude(wikipedia_pageid= None)
            cat_filter = None
            for cat in self.categories:
                if cat_filter is None:
                    cat_filter = Q(category__label = cat)
                else:
                    cat_filter = cat_filter | Q(category__label = cat)
            if cat_filter is not None:
                queryset = queryset.filter(cat_filter)
            
            tcount = queryset.count()
            
            print "Exporting %d tags" % (tcount)
            writer = None
                
            for i,t in enumerate(queryset.order_by("label")):
                
                writer = utils.show_progress(i+1, tcount, t.label, 50, writer)
                #normal category
                row = [t.label,] + [cat.wp_category.label for cat in t.wp_categories.filter(hidden=False)]
                files_path['visible']['csv'].writerow(row)
                
                #hidden category
                row = [t.label,] + [cat.wp_category.label for cat in t.wp_categories.filter(hidden=True)]
                files_path['hidden']['csv'].writerow(row)
                
                #infobox
                for i in t.infoboxes.all():
                    vec = [[p.param_name,p.param_value.replace('\n',"\\n")] for p in i.infoboxparameter_set.all()]
                    ib_params = [num for elem in vec for num in elem]
                    row = [t.label, i.name.strip()] + ib_params
                    files_path['infobox']['csv'].writerow(row)
            
        finally:
            for filedef in files_path.itervalues():
                if filedef.get('file',None):
                    filedef['file'].close()

            
        
        