# -*- coding: utf-8 -*-
from flask import request
from configuration import config, ConfFields
from Cisco79xxPhoneDirectory import app
from flask.views import View

class PhoneBookProviderBase(View):
    """Phonebook provider base class."""
    Routing = {}
    NameFieldKey = "name"
    NumberFieldKey = "number"
    PageParamName = "page"

    def __init__(self, providerKey):
        super(PhoneBookProviderBase, self).__init__()
        self._configuration = config[providerKey]
        self._providerKey = providerKey
        self._host = config.get(ConfFields.ServerAddress)
        self._port = config.get(ConfFields.ServerPort)
        pass

    def dispatch_request(self):
        return app.response_class(self.xmlPhoneBook(), mimetype='text/xml')

    def providerKey(self):
        return self._providerKey

    def isEnabled(self):
        return self._configuration[ConfFields.Enabled]

    def title(self):
        return self._configuration[ConfFields.Title]

    def menuName(self):
        return self._configuration[ConfFields.MenuName]

    def host(self):
        return self._host

    def port(self):
        return self._port

    def getPhoneBook(self):
        """Returns the phonebook array."""
        return []

    def xmlPhoneBook(self):
        """
        Generates the XML in order to display the phone directory.
        """
        page = request.args.get(self.PageParamName)
        directory = self.getPhoneBook()
        if page == None or len(page) == 0:
            return self.xmlPageList(directory)
        else:
            return self.phoneBookPage(directory, page)

    def phoneBookPage(self, directory, page):
        """Creates a phone book page."""
        start, end = self._calculateStartEnd(directory, page)
        xml = '<?xml version="1.0" ?>'
        xml += "<CiscoIPPhoneDirectory>\n"
        xml += "\t<Title>{0}</Title>\n".format(self._configuration[ConfFields.Title])
        xml += "\t<Prompt>{0}</Prompt>\n".format(self._configuration[ConfFields.Prompt])
        for entry in directory[start:end]:
            xml += "\t<DirectoryEntry>\n"
            xml += "\t\t<Telephone>{0}</Telephone>\n".format(entry[self.NumberFieldKey])
            xml += "\t\t<Name>{0}</Name>\n".format(entry[self.NameFieldKey])
            xml += "\t</DirectoryEntry>\n"
        xml += "</CiscoIPPhoneDirectory>\n"
        return xml

    def _getPageSize(self):
        """Returns the page size."""
        return config.get("pagesize", 10)

    def _calculateStartEnd(self, directory, page):
        """Calculates the start and end index of a page."""
        try:
            pageNum = int(page)
        except:
            pageNum = 0

        count = len(directory)
        pageSize = self._getPageSize()
        start = pageNum * pageSize
        if start > count:
            start = count
        end = start + pageSize
        if end > count:
            end = count
        return start, end

    def _getShortListName(self, directory, pageIndex):
        """Creates a short list entry for a page."""
        start, end = self._calculateStartEnd(directory, pageIndex)
        firstEntry = directory[start][self.NameFieldKey][0:8]
        lastEntry = directory[end-1][self.NameFieldKey][0:8]
        result = firstEntry + "... - " + lastEntry+"..." 
        return result

    def xmlPageList(self, directory):
        """Creates a page list."""
        pageSize = self._getPageSize()
        pageCount = len(directory) // pageSize
        if pageCount > 1:
            result = "<CiscoIPPhoneMenu>"
            for i in range(pageCount):
                shortName = self._getShortListName(directory, i)
                result += "<MenuItem>"
                result += "<Name>{0}</Name>".format(shortName)
                result += "<URL>http://{0}:{1}/{2}?{3}={4}</URL>".format(self.host(), 
                                                                         self.port(), 
                                                                         self.providerKey(), 
                                                                         self.PageParamName, 
                                                                         i)
                result += "</MenuItem>"

            result += "<Prompt>Select a page!</Prompt>"
            result += "</CiscoIPPhoneMenu>"
            return result
        else:
            return self.phoneBookPage(directory, 0)


    def responseHandler(self):
        app.response_class(self.xmlPhoneBook(), mimetype='text/xml')

    @staticmethod
    def routeProvider(application, provider, providerKey):
        """Adds the provider to the routing list"""
        #conf = config[providerKey]
        instance = provider(providerKey)
        PhoneBookProviderBase.Routing[providerKey] = instance 
        app.add_url_rule("/" + providerKey, view_func=instance.as_view(providerKey))
        pass



    @staticmethod
    def generateMenue(config):
        """Generates the main menu xml."""
        HOST = config[ConfFields.ServerAddress]
        PORT = config[ConfFields.ServerPort]

        result = "<CiscoIPPhoneMenu>"
        for prov in PhoneBookProviderBase.Routing:
            provider = PhoneBookProviderBase.Routing[prov]
            if provider.isEnabled():
                result += "<MenuItem>"
                result += "<URL>http://{0}:{1}/{2}</URL>".format(HOST, PORT, provider.providerKey())
                result += "<Name>{0}</Name>".format(provider.menuName())
                result += "</MenuItem>"

        result += "<Prompt>{0}</Prompt>".format(config[ConfFields.MenuPrompt])
        result += "</CiscoIPPhoneMenu>"
        return result



