//Editor-Info: -*- C++ -*-

#include <typeinfo>
#include <iostream.h>
#include <string>
#include "pf/system.h"
#include "pf/adapter.h"
#include "pf/transp.h"
#include "protocol/saal/saal.h"
#include "protocol/saal/saalunilink.h"
#include "protocol/saal/saalnnilink.h"
#include "iface/naalif/naaldownprimitives.h"
#include "iface/uaalif/uaaldownprimitives.h"


enum interfaceSide {UNI, NNI};

//void setupLocal(void);
void setupUDP(char *hostname_, interfaceSide side_, int start_, int pdus_);
//void setupATM(int vpi_, int vci_, interfaceSide side_, int start_, int pdus_);


int main(int argc, char *argv[])
{
    interfaceSide side = NNI;
    int pdus = 1000;
    int start = 0;

    if (argc == 1)
    {
//        setupLocal();
    }
    else if (argc > 5)
    {
        cerr << "Usage: "
             << argv[0]
             << " <hostname> [UNI|NNI s|w [<pdus>]]"
             << endl;
        exit(0);
    }
    else
    {
        if (argv[2][0] == 'U')
        {
            side = UNI;
        }
        if (argv[3][0] == 's')
        {
            start = 1;
        }
        if (argc == 5)
        {
            pdus = atoi(argv[4]);
        }
        setupUDP(argv[1], side, start, pdus);
    }
    pfSystem::instance()->run();
    return 0;
}


/*
void setupLocal(void)
{
    SAALlayerManagement *manager = new SAALlayerManagement;

    cpcsAdapter *vp = new cpcsAdapter;

    sscopProtocol *sp1 = new sscopProtocol;
    sp1->setManager(manager);
    sscopProtocol *sp2 = new sscopProtocol;
    sp2->setManager(manager);

    nsscfProtocol *np1 = new nsscfProtocol;
    np1->setManager(manager);
    nsscfProtocol *np2 = new nsscfProtocol;
    np2->setManager(manager);
    
    pfAdapter *a1 = new pfAdapter;
    pfAdapter *a2 = new pfAdapter;

    pfConduit vpc(vp, 1);
    vpc.setId(0);

    pfConduit sp1c(sp1, 1);
    sp1c.setId(11);

    pfConduit sp2c(sp2, 1);
    sp2c.setId(12);

    pfConduit np1c(np1, 1);
    np1c.setId(21);

    pfConduit np2c(np2, 1);
    np2c.setId(22);

    pfConduit ac1(a1, 1);
    ac1.setId(31);

    pfConduit ac2(a2, 1);
    ac2.setId(32);

    ac1.connectToA(np1c);
    np1c.connectToB(ac1);
    np1c.connectToA(sp1c);
    sp1c.connectToB(np1c);
    
    sp1c.connectToA(vpc);
    vpc.connectToA(sp1c);
    vpc.connectToB(sp2c);
    sp2c.connectToA(vpc);

    sp2c.connectToB(np2c);
    np2c.connectToA(sp2c);
    np2c.connectToB(ac2);
    ac2.connectToA(np2c);

    HeapStats::reset();
    
    cout << "AAL-START.req down..." << endl << endl;
    pfMessenger *msg1 = new naalSTARTreq;
    pfMessenger *msg2 = new naalSTARTreq;
    ac1.toA(msg1);
    ac2.toA(msg2);
    return;
}
*/


void setupUDP(char *hostname_, interfaceSide side_, int start_, int pdus_)
{
    pfConduit ac = pfAdapter::createAdapter(0);
    ac.setId(0);

    string host(hostname_);
    saalLink *link = 0;

    if (side_ == NNI)
    {
        saalNNIlink *nniLink =
            saalNNIlink::createUDPNNIlink(0, host, 4444, 4444);
        nniLink->setN1(pdus_);
        link = nniLink;
    }
    else
    {
        link = saalUNIlink::createUDPUNIlink(0, host, 4444, 4444);
    }

    pfConduit sscf = link->getConduit();
    ac.connectToA(sscf);
    sscf.connectToB(ac);

    if (start_ != 0)
    {
        cout << "AAL-START.req down..." << endl << endl;
        if (side_ == NNI)
        {
            naalSTARTreq *msg = new naalSTARTreq;
            pfMsgTransporter *m = pfMsgTransporter::createMsgTransporter(msg);
            sscf.accept(m);
        }
        else
        {
            uaalESTABLISHreq *msg = new uaalESTABLISHreq;
//            pfMsgTransporter *m = pfMsgTransporter::createMsgTransporter(msg);
            sscf.accept(msg);
        }
    }
    return;
}

