import java.lang.reflect.*;
import java.net.URL;
import java.text.*;
import java.util.*;
import org.apache.axis.types.*;
import gw.*;

public class Watch
{
    private GWPort proxy;

    Watch(String gateway)
    {
        try {
            URL portURL = new URL("http://restsoap:AIIT@" + gateway + "/gw/soap");
            GWServiceLocator locator = new GWServiceLocator();
            proxy = locator.getGWPort(portURL);
        }
        catch (Exception e) {
            e.printStackTrace();
            System.exit(2);
        }
    }

    public void watch(long delta)
    {
        double t1, t2, epsilon = 0.00001;
        LinkedList events;
        GW__gwGetStatus_Result soapResult;
        GW__Event_Result event;

        try {
            soapResult = proxy.gwGetStatus();
            t1 = soapResult.getTimestamp();

            while (true) {
                Thread.sleep(1000 * delta);
                t2 = 2147483647;
                events = readEvents(t1, t2, "*", "ffffffffffffffff");
                if (events.size() > 0) {
                    processEvents(events);
                    // Prepare for next [t1,t2). "+ epsilon" to handle boundary
                    event = (GW__Event_Result)events.get(events.size() - 1);
                    t1 = event.getTimestamp() + epsilon;
                }

            }
        }
        catch (Exception e) {
            e.printStackTrace();
            System.exit(2);
        }
    }

    public LinkedList readEvents(double t1, double t2, String name, String addr)
    {
        UnsignedInt offset = new UnsignedInt(0);
        LinkedList eventList = new LinkedList();

        while (true) {
            try {
                GW__eventsRead_Result soapResult;
                soapResult = proxy.eventsRead(t1, t2, name, addr, offset);

                GW__Event_Result[] events = soapResult.getResults();
                for (int i = 0; i < events.length; i++) 
                    eventList.add(events[i]);
                if ((soapResult.getOffset().longValue() + events.length) == 
                    soapResult.getTotal().longValue())
                    break;
                offset = new UnsignedInt(offset.longValue() + events.length);
            }
            catch (Exception e) {
                e.printStackTrace();
                System.exit(2);
            }
        }
        return eventList;
    }

    public void processEvents(LinkedList events)
    {
        GW__Event_Result event;

        try {
            for (int i = 0; i < events.size(); i++) {
                event = (GW__Event_Result)events.get(i);
                GW__Event value = event.getValue();            
                Method m = value.getClass().getMethod("get" + value.getName(), 
                                                      (Class[])null);
                Object o = m.invoke(value, (Object[])null);
                System.out.println(event.getAddr() + " " + event.getTimestamp()
                                   + " " + value.getName() + " " + o);
                // doSomething(event);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            System.exit(2);
        }
    }

    public static void main(String [] args)
    {
        if (args.length != 2) {
            System.out.println("Usage: java Watch gateway delta");
            System.exit(3);
        }
        try {
            String gateway = args[0];
            long delta = Long.valueOf(args[1]).longValue();
            
            Watch watch = new Watch(gateway);   
            watch.watch(delta);
        }
        catch (Exception e) {
            e.printStackTrace();
            System.exit(2);
        }
    }
}