#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    The purpose if this script is to wautomate simple identity uploads
    with an input data set of one identity per page. Moreover, the
    identity instantiation should be done through templating, e.g.
    IdentityTemplate. At present the input identities are assumed
    to be email addresses.

    @copyright: 2008 Lari Huttunen
    @license: MIT <http://www.opensource.org/licenses/mit-license.php>

"""
import re
import sys
import time
import socket
import optparse
from opencollab.meta import Metas
from opencollab.util.wiki import importMetas
from opencollab.util.config import parseOptions
from opencollab.wiki import CLIWiki, WikiFailure


def shred_email_address(addr):
    metas = Metas()
    epoch = "%d" % time.time()
    local, domain = addr.split('@')
    if re.search('\.', local):
        title = local.title()
        id = title.split('.')
        sname = ' '.join(id)
    else:
        sname = local
    metas[addr]["Name"].add(sname)
    metas[addr]["attribution"].add('<<DateTime(%s)>>' % epoch)
    metas[addr]["smtp domain"].add('[[%s]]' % domain.lower())
    metas[addr]["smtp local part"].add(local)
    metas[addr]["type"].add("user")
    return metas


def parse_input_file(path):
    metas = Metas()
    try:
        file = open(path, "r")
        lines = file.readlines()
        file.close()
    except IOError:
        error = "Input file: " + file + " doesn't exist."
        sys.exit(error)
    for line in lines:
        line = line.strip()
        metas.update(shred_email_address(line))
    return metas


def get_identities_from_collab(collab, search):
    pages = Metas()
    emails = Metas()
    tmp = search.split('||')
    keys = tmp[1:-1]
    pages = collab.getMeta(search)
    for page in pages:
        for key in keys:
            if pages[page][key]:
                for value in pages[page][key]:
                    addr = re.sub('[\[\]]', '', value)
                    emails.update(shred_email_address(addr))
    return emails


def main():
    parser = optparse.OptionParser()
    parser.set_usage("%prog [options] <input-file>")
    metas = Metas()
    failed = []
    sect = "upload-identities"
    ops = {}
    ops = parseOptions(parser, sect, search=True, template=True)
    x509 = ops[sect]["x509"]
    x509_ca_file = ops[sect]["x509_ca_file"]
    url = ops["creds"]["url"]
    verbose = ops[sect]["verbose"]
    template = ops[sect]["template"]
    if template is None:
        template = "IdentityTemplate"
    search = ops[sect]["search"]
    args = ops[sect]["args"]
    while True:
        try:
            collab = CLIWiki(ssl_verify_cert=x509, ssl_ca_certs=x509_ca_file, **ops['creds'])
        except WikiFailure:
            print "ERROR: Authentication failed."
        except (UnicodeError, socket.gaierror):
            sys.exit("ERROR: Not a valid URL.")
        else:
            break
    if len(args) == 1:
        file = args.pop()
        if verbose:
            print "NOTE: Parsing input file:", file
        metas.update(parse_input_file(file))
    if search is not None:
        if verbose:
            print "NOTE: Getting identities with:", search, "from\n", url
        metas.update(get_identities_from_collab(collab, search))
    if metas:
        if verbose:
            print "NOTE: Uploading identities to collab:", url
        failed = importMetas(collab, metas, template, verbose)
        if failed:
            for page in failed:
                if verbose:
                    print "ERROR uploading:",  page, repr(metas[page])
                else:
                    print "ERROR uploading:", page
    else:
        if verbose:
            print "NOTE: No identities to upload."

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print "Script interrupted via CTRL-C."
