#!/usr/bin/env python
import sys, os, locale, getopt, logging

import za_extra.restore

import MAPI
from MAPI.Util import *

def usage():
    print "Usage: %s [OPTIONS] user" % os.path.basename(sys.argv[0])
    print "OPTIONS:"
    print "  -h | --host       \tHost to connect with. Default: file:///var/run/zarafa"
    print "  -s | --sslkey-file\tSSL key file for authentication."
    print "  -p | --sslkey-pass\tPassword for the SSL key file."
    print "  -l | --log-file   \tSelect log file."
    print "  --detach          \tDetach the selected or all archive stores before"
    print "                    \t starting the restore procedure. This avoids the"
    print "                    \t archiver from re archiving restored messages."
    print "  --unhook          \tUnhook the selected or all archive stores once"
    print "                    \t the restore process has completed. This implies"
    print "                    \t --detach and only works on archive stores."
    print "  --remove          \tRemove the selected or all archive stores once"
    print "                    \t the restore process has completed. This implies"
    print "                    \t --unhook and only works on archive stores."
    print "  --select-source   \tSelect the source archive(s) by providing a comma"
    print "                    \t separated list of archive indexes. The indexes specify"
    print "                    \t which archives to restore from. The --detach, --unhook"
    print "                    \t and --remove options only apply to the selected"
    print "                    \t archives."
    print "                    \t The archive indexes can be obtained by listing the"
    print "                    \t attached archives for a user: zarafa-archiver -u"
    print "                    \t <user> -l."
    print "  -v | --verbose    \tIncrease console loglevel. Can be specified multiple"
    print "                    \t times."
    print "  -q | --quiet      \tDecrease console loglevel. Can be specified multiple"
    print "                    \t times."
    print "  -N | --dry-run    \tDon't actually modify anything."
    print "  --help            \tShow this help message."
    print ""


def main(argv = None):
    locale.setlocale(locale.LC_ALL, '')

    if argv is None:
        argv = sys.argv

    try:
        opts, args = getopt.gnu_getopt(argv[1:], 'h:s:p:l:vqN', ['help', 'host=', 'sslkey-file=', 'sslkey-pass=', 'log-file=', 'verbose', 'quiet', 'dry-run', 'detach', 'unhook', 'remove', 'select-source', 'log-log-source'])
    except getopt.GetoptError, err:
        # print help information and exit:
	print "Error: %s" % err
        usage()
        return 1

    #defaults
    host = os.getenv('ZARAFA_SOCKET', 'file:///var/run/zarafa')
    sslkey_file = None
    sslkey_pass = None
    log_file = 'za-restore.log'
    clog_level = logging.WARNING
    log_format = '%(asctime)s %(levelname)-8s: %(message)s'
    dry_run = False
    archive_op = za_extra.restore.ArchiveOp.NONE
    archiveIds = None

    for o, a in opts:
        if o == '--help':
            usage()
            return 0
        elif o in ('-h', '--host'):
            host = a
        elif o in ('-s', '--sslkey-file'):
            sslkey_file = a
        elif o in ('-p', '--sslkey-pass'):
            sslkey_pass = a
        elif o in ('-l', '--log-file'):
            log_file = a
        elif o in ('-v', '--verbose'):
            if clog_level - 10 < logging.DEBUG:
                clog_level = logging.DEBUG
            else:
                clog_level -= 10
        elif o in ('-q', '--quiet'):
            if clog_level + 10 > logging.FATAL:
                clog_level = logging.FATAL
            else:
                clog_level += 10
        elif o in ('-N', '--dry-run'):
            dry_run = True
        elif o == '--log-log-source':
            log_format = '%(asctime)s %(levelname)-8s %(pathname)s(%(lineno)u): %(message)s'
        elif o == '--detach' and archive_op < za_extra.restore.ArchiveOp.DETACH:
            archive_op = za_extra.restore.ArchiveOp.DETACH
        elif o == '--unhook' and archive_op < za_extra.restore.ArchiveOp.UNHOOK:
            archive_op = za_extra.restore.ArchiveOp.UNHOOK
        elif o == '--remove' and archive_op < za_extra.restore.ArchiveOp.REMOVE:
            archive_op = za_extra.restore.ArchiveOp.REMOVE
        elif o == '--select-source':
            try:
                archiveIds = [int(str) for str in a.split(',')]
            except ValueError:
                print "Invalid source archives sprecified: '%s'" % a
                usage()
                return 1
        else:
            assert False, "unhandled option"

    logging.basicConfig(level=logging.DEBUG,
                        format=log_format,
                        datefmt='%m-%d %H:%M',
                        filename=log_file,
                        filemode='a')

    console = logging.StreamHandler()
    console.setLevel(clog_level)
    
    formatter = logging.Formatter('%(levelname)s: %(message)s')
    console.setFormatter(formatter)
    
    logging.getLogger('').addHandler(console)

    try:
        session = OpenECSession('SYSTEM', '', host, sslkey_file = sslkey_file, sslkey_pass = sslkey_pass)
    except MAPIError, err:
        if err.hr == MAPI_E_LOGON_FAILED:
            logging.fatal("Failed to logon. Make sure your SSL certificate is correct.")
        elif err.hr == MAPI_E_NETWORK_ERROR:
            logging.fatal("Unable to connect to server. Make sure you specified the correct server.")
        else:
            logging.exception("Unexpected error occurred. hr=%08x" % err.hr)
        return 1

    if len(args) != 1:
        logging.fatal("Exactly one user must be specified")
        usage()
        return 1

    return za_extra.restore.main(session, args[0], logger = logging.getLogger(''), dry_run = dry_run, archive_op = archive_op, archiveIds = archiveIds)

if __name__ == '__main__':
    sys.exit(main())
