import ns3

def main(argv):

    cmd = ns3.CommandLine()
    cmd.Parse (argv)

    # Configuration.

    # Build nodes
    router_0 = ns3.NodeContainer()
    router_0.Create (1)
    term_0 = ns3.NodeContainer()
    term_0.Create (20)
    term_1 = ns3.NodeContainer()
    term_1.Create (20)
    term_3 = ns3.NodeContainer()
    term_3.Create (1)

    # Build link.
    csma_hub_0 = ns3.CsmaHelper()
    csma_hub_0.SetChannelAttribute("DataRate", ns3.DataRateValue(ns3.DataRate(100000000)))
    csma_hub_0.SetChannelAttribute("Delay",  ns3.TimeValue(ns3.MilliSeconds(0)))
    csma_hub_1 = ns3.CsmaHelper()
    csma_hub_1.SetChannelAttribute("DataRate", ns3.DataRateValue(ns3.DataRate(100000000)))
    csma_hub_1.SetChannelAttribute("Delay",  ns3.TimeValue(ns3.MilliSeconds(10000)))
    csma_hub_3 = ns3.CsmaHelper()
    csma_hub_3.SetChannelAttribute("DataRate", ns3.DataRateValue(ns3.DataRate(100000000)))
    csma_hub_3.SetChannelAttribute("Delay",  ns3.TimeValue(ns3.MilliSeconds(0)))

    # Build link net device container.
    all_hub_0 = ns3.NodeContainer()
    all_hub_0.Add (router_0)
    all_hub_0.Add (term_0)
    ndc_hub_0 = csma_hub_0.Install(all_hub_0)
    all_hub_1 = ns3.NodeContainer()
    all_hub_1.Add (router_0)
    all_hub_1.Add (term_1)
    ndc_hub_1 = csma_hub_1.Install(all_hub_1)
    all_hub_2 = ns3.NodeContainer()
    all_hub_2.Add (router_0)
    all_hub_2.Add (term_3)
    ndc_hub_2 = csma_hub_3.Install(all_hub_2)

    # Install the IP stack.
    internetStackH = ns3.InternetStackHelper()
    internetStackH.Install (router_0)
    internetStackH.Install (term_0)
    internetStackH.Install (term_1)
    internetStackH.Install (term_3)

    # IP assign.
    ipv4 = ns3.Ipv4AddressHelper()
    ipv4.SetBase (ns3.Ipv4Address("10.0.0.0"), ns3.Ipv4Mask("255.255.255.0"))
    iface_ndc_hub_0 = ipv4.Assign (ndc_hub_0)
    ipv4.SetBase (ns3.Ipv4Address("10.0.1.0"), ns3.Ipv4Mask("255.255.255.0"))
    iface_ndc_hub_1 = ipv4.Assign (ndc_hub_1)
    ipv4.SetBase (ns3.Ipv4Address("10.0.2.0"), ns3.Ipv4Mask("255.255.255.0"))
    iface_ndc_hub_2 = ipv4.Assign (ndc_hub_2)

    # Generate Route.
    ns3.Ipv4GlobalRoutingHelper.PopulateRoutingTables ()

    # Generate Application.
    port_tcp_0 = 80
    sinkLocalAddress_tcp_0 = ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), port_tcp_0))
    sinkHelper_tcp_0 = ns3.PacketSinkHelper("ns3::TcpSocketFactory", sinkLocalAddress_tcp_0)
    sinkApp_tcp_0 = sinkHelper_tcp_0.Install(term_3)
    sinkApp_tcp_0.Start(ns3.Seconds(0.0))
    sinkApp_tcp_0.Stop(ns3.Seconds(40.0))
    clientHelper_tcp_0 = ns3.OnOffHelper("ns3::TcpSocketFactory", ns3.Address())
    clientHelper_tcp_0.SetAttribute("OnTime", ns3.RandomVariableValue(ns3.ConstantVariable(1)))
    clientHelper_tcp_0.SetAttribute("OffTime", ns3.RandomVariableValue(ns3.ConstantVariable(0)))
    clientApps_tcp_0 = ns3.ApplicationContainer()
    remoteAddress_tcp_0 = ns3.AddressValue(ns3.InetSocketAddress(iface_ndc_hub_2.GetAddress(1), port_tcp_0))
    clientHelper_tcp_0.SetAttribute("Remote", remoteAddress_tcp_0)
    clientApps_tcp_0.Add(clientHelper_tcp_0.Install(term_0))
    clientApps_tcp_0.Start(ns3.Seconds(0.0))
    clientApps_tcp_0.Stop(ns3.Seconds(40.0))
    port_tcp_1 = 80
    sinkLocalAddress_tcp_1 = ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), port_tcp_1))
    sinkHelper_tcp_1 = ns3.PacketSinkHelper("ns3::TcpSocketFactory", sinkLocalAddress_tcp_1)
    sinkApp_tcp_1 = sinkHelper_tcp_1.Install(term_3)
    sinkApp_tcp_1.Start(ns3.Seconds(0.0))
    sinkApp_tcp_1.Stop(ns3.Seconds(40.0))
    clientHelper_tcp_1 = ns3.OnOffHelper("ns3::TcpSocketFactory", ns3.Address())
    clientHelper_tcp_1.SetAttribute("OnTime", ns3.RandomVariableValue(ns3.ConstantVariable(1)))
    clientHelper_tcp_1.SetAttribute("OffTime", ns3.RandomVariableValue(ns3.ConstantVariable(0)))
    clientApps_tcp_1 = ns3.ApplicationContainer()
    remoteAddress_tcp_1 = ns3.AddressValue(ns3.InetSocketAddress(iface_ndc_hub_2.GetAddress(1), port_tcp_1))
    clientHelper_tcp_1.SetAttribute("Remote", remoteAddress_tcp_1)
    clientApps_tcp_1.Add(clientHelper_tcp_1.Install(term_1))
    clientApps_tcp_1.Start(ns3.Seconds(0.0))
    clientApps_tcp_1.Stop(ns3.Seconds(40.0))

    # Simulation.
    # Pcap output.
    # Stop the simulation after x seconds.
    stopTime = 41
    ns3.Simulator.Stop (ns3.Seconds(stopTime))
    # Start and clean simulation.
    ns3.Simulator.Run()
    ns3.Simulator.Destroy()

if __name__ == '__main__':
    import sys
    main(sys.argv)
