import sys
import time

import urllib2
import socket
from xml.dom import minidom
import misc
import home
import config


class CredentialsParseError(Exception):

    def __init__(self, value):
        self.value = value

    def __str__(self):
        return self.value


def download_credentials():

    # forced wait
    time.sleep(1)
    # optional longer wait
    if '--slowly' in sys.argv: time.sleep(5)

    old_timeout =  socket.getdefaulttimeout()
    try:
        socket.setdefaulttimeout(config.creddownload_timeout)
        d = urllib2.urlopen(misc.get_credentials_url())
        r = d.read()
        d.close()
        socket.setdefaulttimeout(old_timeout)
        return r
    except:
        socket.setdefaulttimeout(old_timeout)
        return None


def load_credentials():

    h = home.Home()
    if not h.credentials_filename:
        return None
    xml_text = misc.load_from_file(h.credentials_filename)
    return xml_text
    

def save_credentials(xml_text):
    h = home.Home()
    if not h.credentials_filename:
        return False
    try:
        f = open(h.credentials_filename, 'w')
        f.write(xml_text)
        f.close()
        return True
    except:
        return False
    

def process_credentials(xml):

    id = None
    key = None

    if len(xml.childNodes) != 1: raise CredentialsParseError('multiple root elements found')
    config = xml.firstChild
    if config.localName != 'credentials': raise CredentialsParseError('root element is not <credentials>')
    for c in config.childNodes: 
        if c.nodeType == c.TEXT_NODE: continue
        if c.nodeType != c.ELEMENT_NODE: continue

        if c.localName == 'id': 
            id = c.getAttribute('value')
        elif c.localName == 'key': 
            key = c.getAttribute('value')
        else:
            raise DevicesParseError('unknown element <%s>' % c.localName)

    if not id or not key:
        return False
    else:
        return (id, key)


def parse_credentials(xml_text):
    try:
        xmldoc = minidom.parseString(xml_text)
        r = process_credentials(xmldoc)
        return r
    except:
        return False
        

def update_credentials_async():

    xml_text = load_credentials()
    if not xml_text:
        xml_text = download_credentials()
        if not xml_text:
            return False
        save_credentials(xml_text)
    
    cred = parse_credentials(xml_text)
    return cred
