/** \example BasicSample.java */
/** \@code */

// An absolute minimal example program.

package com.marketfactory.sample;

import com.marketfactory.api.*;

import java.util.logging.Logger;
import java.io.IOException;


public class BasicSample
{
    private static final String DEFAULT_HOSTNAME = "ny9.marketfactory.com";
    private static final int DEFAULT_PORT = 10033;

    private static final String USAGE_PARAMETERS = "username password [hostname] [port]";


    public static void main(String args[]) throws IOException, InterruptedException
    {
        // Parse command-line arguments, 1980's-style.
        if (args.length < 2) {
            throw new RuntimeException("Not enough parameters provided. Parameters: " + USAGE_PARAMETERS);
        }

        final String username = args[0];
        final String password = args[1];
        final String hostname = args.length >=3 ? args[2] : DEFAULT_HOSTNAME;
        final int port = args.length >=4 ? Integer.valueOf(args[3]) : DEFAULT_PORT;

        // Setup logging.
        Logger log = Logger.getLogger("example");

        // Connect to our server.
        try {
            MFClient client = MFClient.open(username, password, hostname, port);
            if ( client == null ) {
                log.severe("Could not connect.");
                System.exit(1);
            }

            // Create a handler to receive all the callbacks.
            MFHandler handler = new APIHandler(log);

            // Reconnect after each return of run() unless client.stop() is called.
            APIResult status;
            while (true) {
                // Dispatch messages on the handler (until client.stop() is called).
                status = client.run(handler);
                if (status == APIResult.OK)
                    break;
                log.info("Loop until successful connection...");
                // Loop until successful connection.
                while (!client.isConnected()) {
                    client.connect();
                }
            }

            System.exit(status.get());
        }
        catch (IOException e) {
            log.severe("Error: " + e);
        }
    }
}

class APIHandler extends AbstractMFHandler
{
    private Logger log;
    private int numActiveFeeds = 0;
    private int numHeartbeats = 0;

    APIHandler(Logger log)
    {
        this.log = log;
    }

    public void onStart(MFClient client)
    {
        log.info("===== onStart");
        client.setStickySubscriptions(true);

        APIFeed feed = client.getFeedByName("HOTSPOT");
        assert feed != null;

        // Subscribe to some market data and some trading on the same feed.
        for( APIMarket market : feed.marketList ){
            client.subscribeMD(market.feedID, market.marketID);
        }
        client.subscribeOF(feed.feedID);
    }

    public void onStop(MFClient client)
    {
        log.info("===== onStop");
    }

    public void onDisconnect(MFClient client)
    {
        log.info("===== onDisconnect");
    }

    public void onConnect(MFClient client)
    {
        log.info("===== onConnect");
    }

    public void onHeartbeat(Heartbeat heartbeat, MFClient client)
    {
        if ( numHeartbeats++ % 1000 == 0 ) {
            log.info("===== NumHeartbeats: " + numHeartbeats);
        }
        if ( heartbeat.activeFeeds.length != numActiveFeeds ) {
            numActiveFeeds = heartbeat.activeFeeds.length;
            log.info("===== onHeartbeat update: " + heartbeat);
        }
    }

    public void onSubscriptionEvent(SubscriptionEvent event, MFClient client)
    {
        log.info("===== onSubscriptionEvent: " + event);
    }

    public void onMarketData(MarketView mvd, MFClient client)
    {
        log.info("===== onMarketData: " + mvd);
    }

    public void onBatchComplete(int batchDefID, MFClient client)
    {
        log.info("===== onBatchComplete: ");
    }

    public void onEventReport(EventReport eventReport, MFClient client)
    {
        log.info("===== EventReport: ");
    }

    public void onOrderReceived(OrderReceived orderReceived, MFClient client)
    {
        log.info("===== onOrderReceived: " + orderReceived);
    }

    public void onOrderRejected(OrderRejected orderRejected, MFClient client)
    {
        log.info("===== onOrderRejected: " + orderRejected);
    }

    public void onOrderSubmitted(OrderSubmitted orderSubmitted, MFClient client)
    {
        log.info("===== onOrderSubmitted: " + orderSubmitted);
    }

    public void onOrderCanceled(OrderCanceled orderCanceled, MFClient client)
    {
        log.info("===== onOrderCanceled: " + orderCanceled);
    }

    public void onOrderCancelRejected(OrderCancelRejected orderCancelRejected, MFClient client)
    {
        log.info("===== onOrderCancelRejected: " + orderCancelRejected);
    }

    public void onDropCopy(DropCopy dropCopy, MFClient client)
    {
        log.info("===== onDropCopy:" + dropCopy);
    }

    public void onTradeCapture(TradeCapture tradeCapture, MFClient client)
    {
        log.info("===== onTradeCapture: " + tradeCapture);
    }

    public void onOrderDone(OrderDone orderDone, MFClient client)
    {
        log.info("===== onOrderDone: " + orderDone);
    }
}

/** \@endcode */
