"""
ns3lte.py - This script demonstrates using CORE with the ns-3 LTE model.
*** Note that this script is not currently functional, see notes below. ***
- issues connecting TapBridge with LteNetDevice
"""

import logging
import optparse
import sys

import ns.core
import ns.mobility
from corens3.obj import Ns3LteNet
from corens3.obj import Ns3Session

from core.nodes import ipaddress


def ltesession(opt):
    """
    Run a test LTE session.
    """
    session = Ns3Session(1, persistent=True, duration=opt.duration)
    lte = session.create_node(cls=Ns3LteNet, name="wlan1")
    lte.setsubchannels(range(25), range(50, 100))
    if opt.verbose:
        ascii_helper = ns.network.AsciiTraceHelper()
        stream = ascii_helper.CreateFileStream('/tmp/ns3lte.tr')
        lte.lte.EnableAsciiAll(stream)

    prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
    mobb = None
    nodes = []
    for i in xrange(1, opt.numnodes + 1):
        node = session.addnode(name="n%d" % i)
        mob = ns.mobility.ConstantPositionMobilityModel()
        mob.SetPosition(ns.core.Vector3D(10.0 * i, 0.0, 0.0))
        if i == 1:
            # first node is nodeb
            lte.setnodeb(node)
            mobb = mob
        node.newnetif(lte, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
        nodes.append(node)
        if i == 1:
            _tmp, ns3dev = lte.findns3dev(node)
            lte.lte.AddMobility(ns3dev.GetPhy(), mob)
        if i > 1:
            lte.linknodeb(node, nodes[0], mob, mobb)

    session.thread = session.run(vis=opt.visualize)
    return session


def main():
    """
    Main routine when running from command-line.
    """
    usagestr = "usage: %prog [-h] [options] [args]"
    parser = optparse.OptionParser(usage=usagestr)
    parser.set_defaults(numnodes=4, duration=600, verbose=False, visualize=False)

    parser.add_option("-d", "--duration", dest="duration", type=int,
                      help="number of seconds to run the simulation")
    parser.add_option("-n", "--numnodes", dest="numnodes", type=int,
                      help="number of nodes")
    parser.add_option("-z", "--visualize", dest="visualize",
                      action="store_true", help="enable visualizer")
    parser.add_option("-v", "--verbose", dest="verbose",
                      action="store_true", help="be more verbose")

    def usage(msg=None, err=0):
        sys.stdout.write("\n")
        if msg:
            sys.stdout.write(msg + "\n\n")
        parser.print_help()
        sys.exit(err)

    opt, args = parser.parse_args()

    if opt.numnodes < 2:
        usage("invalid numnodes: %s" % opt.numnodes)

    for a in args:
        logging.warn("ignoring command line argument: '%s'", a)

    return ltesession(opt)


def cleanup():
    logging.info("shutting down session")
    session.shutdown()


if __name__ == "__main__":
    session = main()