# Kanbanara Export Component
# Written by Rebecca Shalfield between 2013 and 2017
# Copyright (c) Rebecca Shalfield 2013-2017
# Released under the GNU AGPL v3

'''Kanbanara's Export Component'''

import datetime
import json
import logging
import os
import re
import urllib.parse

import cherrypy
from cherrypy.lib.static import serve_file
from kanbanara import Kanbanara
from pymongo import MongoClient


class Export(Kanbanara):
    '''Kanbanara's Export Component'''

    @cherrypy.expose
    def export_cards_as_json(self):
        """Allows all the cards in the selected project and state(s) to be exported in JSON format"""
        username = Kanbanara.check_authentication(f'/{self.component}')
        session_id = Kanbanara.cookie_handling(self)
        session_document = self.sessions_collection.find_one({"session_id": session_id})
        _, required_states = self.get_displayable_columns()
        _, _, owner_reviewer_search_criteria = self.get_filtered_search_criteria(session_document,
                                                                                 required_states)
        filepath = os.path.join(self.current_dir, '..', 'downloads', username+'_cards.json')
        epoch = datetime.datetime.utcnow()
        while filepath in self.file_locks and self.file_locks[filepath] > epoch - self.timedelta_minute:
            True

        self.file_locks[filepath] = datetime.datetime.utcnow()
        with open(filepath, 'w') as outfile:
            tidied_documents = []
            for document in self.cards_collection.find(owner_reviewer_search_criteria):
                for unwanted in ['_id']:
                    del document[unwanted]

                tidied_documents.append(document)

            json.dump(tidied_documents, outfile, indent=4, default=self.json_type_handler)
            del self.file_locks[filepath]

        return serve_file(filepath, "application/x-download", "attachment")

    @cherrypy.expose
    def session_as_json(self):
        """Displays a user's own session in JSON format"""
        Kanbanara.check_authentication(f'/{self.component}/session_as_json')
        session_id = Kanbanara.cookie_handling(self)
        session_document = self.sessions_collection.find_one({"session_id": session_id})
        if session_document:
            content = []
            content.append(Kanbanara.header(self, "session_as_json", "Session As JSON"))
            content.append(Kanbanara.filter_bar(self, 'session_as_json'))
            content.append(Kanbanara.menubar(self))
            content.append(self.insert_page_title_and_online_help(session_document,
                                                                  "session_as_json",
                                                                  "Session As JSON"))
            content.append('<p class="json">')
            content.append(self.dictionary_as_json('html', session_document, 0))
            content.append('</p>')
            content.append(Kanbanara.footer(self))
            return "".join(content)
        else:
            raise cherrypy.HTTPRedirect("/kanban/index", 302)

    def __init__(self):
        """Initialisation"""
        self.component = 'export'

        Kanbanara.__init__(self)

        self.current_dir = os.path.dirname(os.path.abspath(__file__))

        logging.basicConfig(level=logging.DEBUG,
                            format='%(asctime)s - %(levelname)s - %(message)s',
                            filename=os.path.join(self.current_dir, '..', 'logs', 'kanbanara.log'),
                            filemode='w'
                           )

        # Initialisation Settings
        self.mongodb_host, self.mongodb_port, self.mongodb_username, self.mongodb_password, self.mongodb_bindir = Kanbanara.read_mongodb_ini_file(self)

        # Connect to MongoDB on given host and port
        if self.mongodb_username and self.mongodb_password:
            modified_username = urllib.parse.quote_plus(self.mongodb_username)
            modified_password = urllib.parse.quote_plus(self.mongodb_password)
            connection = MongoClient('mongodb://' + modified_username + ':' + modified_password + '@' +
                                     self.mongodb_host + ':' + str(self.mongodb_port))
        else:
            connection = MongoClient(self.mongodb_host, self.mongodb_port)

        # Connect to 'kanbanara' database, creating if not already exists
        kanbanara_db = connection['kanbanara']

        # Connect to 'projects' collection
        self.projects_collection = kanbanara_db['projects']
        for attribute in ['project']:
            self.projects_collection.create_index(attribute, unique=True, background=True)

        # Connect to 'sessions' collection
        self.sessions_collection = kanbanara_db['sessions']
        for attribute in ['session_id']:
            self.sessions_collection.create_index(attribute, unique=True, background=True)

        for attribute in ['lastaccess']:
            self.sessions_collection.create_index(attribute, unique=False, background=True)

        # Connect to 'members' collection
        self.members_collection = kanbanara_db['members']
        for attribute in ['username']:
            # TODO - username attribute should be unique but get error when unique=true set
            self.members_collection.create_index(attribute, unique=False, background=True)

        # Connect to 'cards' collection
        self.cards_collection = kanbanara_db['cards']

        self.recent_activities = []

    @cherrypy.expose
    def index(self):
        """Redirects you to the kanban board"""
        raise cherrypy.HTTPRedirect("/kanban", 302)

CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
conf = {'/': {'tools.staticdir.root':   CURRENT_DIR,
              'tools.sessions.on':      True,
              'tools.sessions.locking': 'explicit'
             }}
for directory in ['css', 'images']:
    if os.path.exists(CURRENT_DIR+os.sep+directory):
        conf['/'+directory] = {'tools.staticdir.on':  True,
                               'tools.staticdir.dir': directory}

cherrypy.tree.mount(Export(), '/export', config=conf)
