import plistlib, os, urlparse

KEYWURL_PLIST_PATH = os.path.expanduser("~/Library/Application Support/Keywurl/Keywords.plist")
ALFRED_PLIST_PATHS = [os.path.expanduser("~/Library/Application Support/AlfredApp/customsites.plist"),
                      os.path.expanduser("~/Library/Application Support/Alfred/customsites.plist")]

#Found at http://stackoverflow.com/questions/1066933/python-extract-domain-name-from-url
def urlHost(url):
    try:
        return '.'.join(urlparse.urlparse(url).netloc.split('.'))
    except:
        return None

KEYWURL_PARAMS = ["{input}", "{1}", "{2}", "{3}", "{4}", "{5}", "{6}", 
                  "{7}",  "{8}", "{9}", ]

def alfredEntryForKeywurlEntry(key, keywurlEntry):
    
    keyword = key
    
    url = keywurlEntry["expansion"]
    for keywurlParam in KEYWURL_PARAMS:
        if (keywurlParam in url):
            print 
            print "Converting entry with shortcut: %s and url: %s" % (key, keywurlEntry["expansion"])
            print "Error : Alfred only supports entries using 'complete query' in Keywurl."
            print "        Skipping this one. You can rerun this script if you change your Keywurl entry."
            return False

    text = urlHost(url)
    if (not text):
        print 
        print "Converting entry with shortcut: %s and url: %s" % (key, keywurlEntry["expansion"])

    while (not text):
        text = raw_input("Could not find hostname in Keywurl entry, please provide one: ")

    utf8 = False
    
    return {"keyword" : key,
            "url"     : url,
            "text"    : text,
            "utf8"    : utf8}
    
    
def alfredizeKeywurlEntries(keywurl):
    
    keywurlEntries = keywurl["keywords"]
    alfredized = []
    
    for key, entry in keywurlEntries.iteritems():
        converted = alfredEntryForKeywurlEntry(key, entry)
        if (converted):
            alfredized.append(converted)
            
    return alfredized
    
    
def mergeKeywurlEntriesIntoAlfred():
    
    # Parse plists
    keywurl = plistlib.readPlist(KEYWURL_PLIST_PATH)
    alfred  = []
    for filepath in ALFRED_PLIST_PATHS:
        if (os.access(filepath, os.R_OK)):
            alfred.extend(plistlib.readPlist(filepath))

    # Convert Keywurl entries to Alfred entries
    alfredized = alfredizeKeywurlEntries(keywurl)

    # Convert Alfred entry from array to dict
    alfredDict = dict([(entry["keyword"], entry) for entry in alfred])
    
    # Merge and check for conflict in keywords between Keywurl and Alfred
    for newEntry in alfredized:
        if (newEntry["keyword"] in alfredDict.keys()):
            keyword = newEntry["keyword"]
            keywurlExpansion = newEntry["url"]
            alfredExpansion  = alfredDict[keyword]["url"]
            # Only complain if there is a difference, otherwise this could
            # be from running the script multiple times
            if (keywurlExpansion != alfredExpansion):
                print "CONFLICTING ENTRIES:"
                print "\tKeywurl entry : %s -> %s" % (keyword, newEntry["url"])
                print "\tAlfred entry  : %s -> %s" % (keyword, alfredDict[keyword])
                print "\tRename one of them and run this script again."
                
        else:
            alfred.append(newEntry)
            
    return alfred
    
def addKeywurlEntriesToAlfred():

    try:
        updatedAlfredEntries = mergeKeywurlEntriesIntoAlfred()
        # Write out new plist
        print 
        print "Writing imported custom searches to Alfred's plist."
        for filepath in ALFRED_PLIST_PATHS:
            directory = filepath.rsplit("/", 1)[0]
            if (os.path.exists(directory)):
                plistlib.writePlist(updatedAlfredEntries, filepath)
        print "RESTART ALFRED"
    except Exception:
        print "MAJOR ERROR: Nothing imported."
        raise
        
    

if __name__ == "__main__":
    addKeywurlEntriesToAlfred()
