#!/usr/bin/python
from __future__ import absolute_import, division, print_function

import argparse
from io import BytesIO
try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO
import sys
from urllib2 import urlopen
import re

from PIL import Image
import xlsxwriter

from dossier.store import Store
from dossier.models.folder import Folders
from dossier.models.subtopic import subtopics
import kvlayer
import yakonfig


class Factory(yakonfig.factory.AutoFactory):
    config_name = 'sortingdesk_report'
    kvlclient = property(lambda self: kvlayer.client())
    auto_config = lambda self: []


def main():
    p = argparse.ArgumentParser(
        description='SortingDesk report generation tool')
    p.add_argument('-c', '--config', required=True,
                   help='dossier stack YAML config file')
    p.add_argument('-o', '--output', required=True,
                   help='path to write Excel workbook file')
    p.add_argument(
        '-u', '--user', default='unknown', help='user name (default=ALL)')
    p.add_argument('folder', help='folder name')
    p.add_argument('subfolder', nargs='?', default=None,
                   help='subfolder name (default=ALL)')
    args = p.parse_args()

    config = yakonfig.set_default_config([kvlayer], filename=args.config)
    factory = Factory(config)
    store = factory.create(Store)

    # Instantiate and run report generator.
    folders = Folders(kvlayer.client())
    gen = ReportGenerator(store, folders, args.folder,
                          subfolder_name=args.subfolder, user=args.user)
    with open(args.output, 'wb+') as out:
        gen.run(out)


class ReportGenerator(object):
    '''Generates a report in Excel format.'''

    def __init__(self, store, folders, folder_name, subfolder_name=None, user='unknown'):
        '''Class constructor.

        :param folders: Reference to folder.Folders instance
        :param folder: folder name to generate report for
        :param subfolder: subfolder name; must be contained by folder and can
                          be None
        :param user: Generate report on data created by specified user.
        '''
        self.store = store
        self.folders = folders
        self.workbook = None
        self.formats = {}
        self.folder_name = folder_name
        self.subfolder_name = subfolder_name
        self.user = user

    @property
    def folder_id(self):
        return Folders.name_to_id(self.folder_name)

    @property
    def subfolder_id(self):
        return Folders.name_to_id(self.subfolder_name)

    def run(self, output):
        '''Generate the report to the given output.

        :param output: writable file-like object or file path
        '''
        # Ensure folder exists.
        if self.folder_id not in self.folders.folders(self.user):
            print("E: folder not found: %s" % self.folder_name,
                  file=sys.stderr)
            return

        # Create workbook.
        wb = self.workbook = xlsxwriter.Workbook(output)

        # Create the different styles used by this report generator.
        self.formats['title'] = wb.add_format({'font_size': '18',
                                               'bold': True})

        self.formats['default'] = wb.add_format({'align': 'top'})
        self.formats['bold'] = wb.add_format({'bold': True})

        self.formats['header'] = wb.add_format({
            'bold': True,
            'align': 'center',
            'valign': 'top',
            'font_size': '14',
            'font_color': '#506050',
            'bg_color': '#f5f5f5',
            'right': 1,
            'border_color': 'white'})

        self.formats['pre'] = wb.add_format({'font_name': 'Courier',
                                             'valign': 'top'})

        self.formats['link'] = wb.add_format({'valign': 'top',
                                              'font_color': 'blue',
                                              'underline': True})

        self.formats['type_text'] = wb.add_format({
            'font_color': '#BF8645',
            'valign': 'top',
            'align': 'center'})

        self.formats['type_image'] = wb.add_format({
            'font_color': '#84BF45',
            'valign': 'top',
            'align': 'center'})

        # Generate report for a specific subfolder or *all* subfolders of
        # self.folder .
        if self.subfolder_id is None:
            self._generate_report_all()
        else:
            self._generate_report_single(self.subfolder_id)

        # done and outta here
        self.workbook.close()

    def _generate_report_all(self):
        '''Generate report for all subfolders contained by self.folder_id.'''
        assert self.workbook is not None
        count = 0