package deltafeedapp.subscribers;
import java.util.Collection;
import java.util.Iterator;

import deltafeedapp.pushmodehandlers.PushModeHandler;
import jayeson.lib.feed.api.IBetEvent;
import jayeson.lib.feed.api.IBetMatch;
import jayeson.lib.feed.api.IBetRecord;
import jayeson.lib.feed.api.ISnapshot;
import jayeson.lib.feed.api.twoside.IB2Match;
import jayeson.lib.feed.api.twoside.IB2Record;
import jayeson.lib.sports.client.FeedView;
import jayeson.lib.sports.client.SportsFeedClient;
import jayeson.lib.sports.client.SportsFeedFactory;

public class StreamFilterConfigSubscriber {

	public static void main(String[] args) throws InterruptedException {	
		/* Creating factory before instantiating SportsFeedClient */
		SportsFeedFactory factory = new SportsFeedFactory();
		
		/* Create SportsFeedClient with custom config file 
		 * The book filter and market filter are implemented in the sample custom config (conf/customStreamFilterConfig.json)
		 * It will filter out odds that are not from IBC, SBO and odds from EARLY market 
		 */
		SportsFeedClient client = factory.createFromConfigFile("customStreamFilterConfig.json");
		
		/* Start the client */
		client.start();
		
		/* A single client supports multiple views. 
		   Views also determine the shape of records that will be retrieved. 
		   Below are IBetMatch view created with no filters applied. */
		FeedView<IBetMatch> noFilterIBetMatchFeedView = client.view(IBetMatch.class);
		
		/* You can now retrieve data from the newly created view. You can choose to process this data by polling the view or by attaching an event handler. */
		/* Process events by attaching an event handler */
		PushModeHandler myHandler = new PushModeHandler("StreamFilterByMarketBookConfig");
		noFilterIBetMatchFeedView.register(myHandler);
		
		/* Read data by polling the view from a feed view, basically it is to repeatedly poll for the latest snapshot */
		while (true) {
		    /* You can update 'IB2Match' to 'SoccerMatch' or 'TennisMatch' or etc. according to the type of FeedView you initialized */
			int limit = 3;
			ISnapshot<IBetMatch> snapshot = noFilterIBetMatchFeedView.snapshot();
		    Collection<IBetMatch> matches = snapshot.matches();
		    System.out.print("There are currently " + matches.size() + " matches. ");
		    System.out.print("Only printing "+limit+" matches/events/records\n");
		    printMatches(matches,limit);
		    /* Perform business logic on the list of matches */
		    Thread.sleep(5000);
		}
		
		/* Once an EventHandler is no longer needed, it should be unregistered from a view */
//		filterView.unregister(myHandler);
//		client.removeView(filterView);
		
	}
	/* Below are printing function for display purposes */
	public static <M extends IBetMatch> void printMatches(Collection<M> matches, int limit) {
	    Iterator<M> it = matches.iterator();
	    for (int i = 0; i < limit && it.hasNext(); i++) {
	        M match = it.next();
	        System.out.println("-------------------------");
	        System.out.println(match.sportType() + ":" + match.league() + ":" + ((IB2Match)match).participantOne() + ":" + ((IB2Match)match).participantTwo());
	        printEvents(match.events(), limit);
	    }
	}
	
	public static <E extends IBetEvent> void printEvents(Collection<E> events, int limit) {
        Iterator<E> it = events.iterator();
        for (int i = 0; i < limit && it.hasNext(); i++) {
        	IBetEvent event = it.next();
            printRecords(event.records(), limit);
        }
	}
	
	public static <R extends IBetRecord> void printRecords(Collection<R> records, int limit) {
	    Iterator<R> it = records.iterator();
        for (int i = 0; i < limit && it.hasNext(); i++) {
        	IBetRecord record = it.next();
            System.out.println(record.source() + ":" + ((IB2Record)record).pivotType() + ":" + ((IB2Record)record).oddType() + ":" + ((IB2Record)record).rateOver() + ":" + ((IB2Record)record).rateUnder() + ":" + ((IB2Record)record).rateEqual());
        }
	}
	
	public static <M extends IBetMatch> void printMatches(Collection<M> matches) {
		printMatches(matches, matches.size());
	}
	
	public static <E extends IBetEvent> void printEvents(Collection<E> events) {
		printEvents(events, events.size());
	}
	
	public static <R extends IBetRecord> void printRecords(Collection<R> records) {
		printRecords(records, records.size());
	}
}