#!/usr/bin/env python2.7
# vim: tabstop=4 softtabstop=4 shiftwidth=4 textwidth=80 smarttab expandtab
"""
* Copyright (C) 2011   Sangoma Technologies Corp.
* All Rights Reserved.
*
* Author(s)
* William Adam <william.adam@sangoma.com>
*
* This code is Sangoma Technologies Confidential Property.
* Use of and access to this code is covered by a previously executed
* non-disclosure agreement between Sangoma Technologies and the Recipient.
* This code is being supplied for evaluation purposes only and is not to be
* used for any other purpose.
"""
import sys
import os
import glob
import json
import re
from optparse import OptionParser

base = os.path.dirname(os.path.realpath(__file__))
# Create OUR libs path
lib_path = os.path.normpath(base + '/../libs')
# Append OUR lib to path
sys.path.append(lib_path)
# Ready to play with our libs :)

# Create logger
import logging
import logging.handlers

logger = logging.getLogger(os.path.basename(os.path.abspath(sys.argv[0])))
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
logger.addHandler(handler)

def verify_socket_addr(value):
    '''
    Split and return strings of type <xxxx:yy> into tuple
    (xxxx, yy) with value checking
    '''
    if value is None or value is '':
        return None, None
    elif not isinstance(value, str):
        raise TypeError('Must pass a string!')

    if ':' in value:
        ip, port = value.split(':')
        if len(port) == 0:
            port = None
    else:  # either an ip OR port
        try: # value may be just port int
            int(value)
            port = value
            ip = None
        except ValueError:
            ip = value
            port = None

    import ipaddr

    if ip is not None:
        if ip == '0.0.0.0' or '*' in ip:
            raise ValueError("'" + ip + "' is not a valid ip address!")
        # run the address through ipaddr as a sanity check
        # and to catch any incorrect addresses
        ipaddr.IPv4Address(ip)

    if port == '*':
        raise ValueError("'" + port + "' is not a valid port address!")

    return ip, port


def main(argv):

    parser = OptionParser()
    # Define args
    parser.add_option("--package", dest="safe_package",
                      help="path to safepy python package")
    parser.add_option("--script", dest="script",
                      help="path to safepy python script to execute")
    parser.add_option("--server", dest="server_socket",
                      help="Socket address serving the rest connection")

    # Parse args
    (options, args) = parser.parse_args()

    # import the requested safepy module
    package_name = options.safe_package
    # default to product_release
    if package_name is None:
        package_name = 'product_release'

    # import the requested safepy module
    module = __import__(package_name)

    # create product
    product = module.Product(logger)

    # Do we have the server argument ?
    server_socket = options.server_socket
    if server_socket is None:
        # No server address specify, most likely trying to use local server
        # Try to find out the httpd listen directive
        if os.path.isfile('/usr/webconfig/conf/httpd.d/server_local.conf'):
            # Extract Listen argument
            r = re.compile("Listen\s+?([0-9.:].*)")
            m = r.search( 
                    open(
                        '/usr/webconfig/conf/httpd.d/server_local.conf',
                        "r").read())
            if m:
                server_socket = m.group(1)

    ip, port = verify_socket_addr(server_socket)

    product.connect(ip, port)

    # Script or interactive console
    if options.script:
        # Execute script
        rc = execfile(options.script, globals(), locals())
        return rc
    else:
        # TODO: need to be able to call 'application' instead of 'nsc'
        version = product.nsc.version.retrieve()
        # Banner
        print "Welcome to " + version['full_name'] + " - " + version['product_version']
        # Start interactive console
        import code
        code.interact(local=locals())




if __name__ == '__main__':
    try:
        sys.exit(main(sys.argv))
    except SystemExit:
        raise
    except Exception, e:
        sys.stderr.write("Exception caught: %s\n" % (e))
        raise
