package deltafeedapp.pushmodehandlers;
import java.util.Collection;
import java.util.Date;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jayeson.lib.feed.core.B2Record;
import jayeson.lib.feed.soccer.SoccerEvent;
import jayeson.lib.feed.soccer.SoccerEventState;
import jayeson.lib.feed.soccer.SoccerMatch;
import jayeson.lib.feed.soccer.SoccerRecord;
import jayeson.lib.sports.client.DeleteEvent;
import jayeson.lib.sports.client.DeleteMatch;
import jayeson.lib.sports.client.DeleteOdd;
import jayeson.lib.sports.client.DeltaEventHandler;
import jayeson.lib.sports.client.InsertEvent;
import jayeson.lib.sports.client.InsertMatch;
import jayeson.lib.sports.client.InsertOdd;
import jayeson.lib.sports.client.Reset;
import jayeson.lib.sports.client.UpdateEvent;
import jayeson.lib.sports.client.UpdateMatch;
import jayeson.lib.sports.client.UpdateOdd;

public class SoccerMatchPushModeHandler implements DeltaEventHandler<SoccerMatch, SoccerEvent, SoccerRecord> {
	private static Logger log = LoggerFactory.getLogger(SoccerMatchPushModeHandler.class);

	private String identifier;

	public SoccerMatchPushModeHandler(String identifier) {
		this.identifier = identifier;
	}

	public String convertEpochToReadable(long epoch){
		long new_epoch = (long) epoch * 1000;
		Date date = new Date(new_epoch);
		return date.toString();
	}
	
	@Override
	public void onInsertMatch(InsertMatch<SoccerMatch> event) {
		String identifier = "PUSH_INSERT_MATCH";
		printMatch(identifier, event.get());
	}

	@Override
	public void onUpdateMatch(UpdateMatch<SoccerMatch> event) {
		String identifier = "PUSH_UPDATE_MATCH";
		printMatch(identifier, event.get());
	}

	@Override
	public void onDeleteMatch(DeleteMatch<SoccerMatch> event) {
		String identifier = "PUSH_DELETE_MATCH";
		printMatch(identifier, event.get());
	}

	@Override
	public void onInsertEvent(InsertEvent<SoccerEvent> event) {
		String identifier = "PUSH_INSERT_EVENT";
		printEvent(identifier, event.get());
	}

	@Override
	public void onUpdateEvent(UpdateEvent<SoccerEvent> event) {
		String identifier = "PUSH_UPDATE_EVENT";
		printEvent(identifier, event.get());
	}

	@Override
	public void onDeleteEvent(DeleteEvent<SoccerEvent> event) {
		String identifier = "PUSH_DELETE_EVENT";
		printEvent(identifier, event.get());
	}

	@Override
	public void onInsertOdd(InsertOdd<SoccerRecord> event) {
		String identifier = "PUSH_INSERT_ODD";
		printRecord(identifier, event.get());
	}

	@Override
	public void onUpdateOdd(UpdateOdd<SoccerRecord> event) {
		String identifier = "PUSH_UPDATE_ODD";
		printRecord(identifier, event.get());
	}

	@Override
	public void onDeleteOdd(DeleteOdd<SoccerRecord> event) {
		String identifier = "PUSH_DELETE_ODD";
		printRecord(identifier, event.get());
	}
	
	@Override
	public void onReset(Reset resetKeys) {
		resetKeys.get().stream().forEach(key -> {
			log.info("PUSH_RESET {}",key); 
		});
	}
	
	@Override
	public void onSwitchFilterStart() {
		log.info("SWITCH_FILTER_START");
	}
	
	@Override
	public void onSwitchFilterEnd() {
		log.info("SWITCH_FILTER_END");
	}
	
	@Override
	public void onFullSnapshotStart() {
		log.info("FULLSNAPSHOT_START");
	}
	
	@Override
	public void onFullSnapshotEnd() {
		log.info("FULLSNAPSHOT_END");
	}
	
	@Override
	public void onSwitchFilterFail() {
		log.info("SWITCH_FILTER_FAIL");
	}
	
	private void printRecord(String identifier, Collection<SoccerRecord> collection) {
		collection.stream()
				.forEach(r -> log.info(this.identifier + " " + identifier + " " + r.matchId() + "_" + r.eventId() + "_"
						+ r.source() + "_" + r.oddType() + "_" + r.id() + "_" + ((B2Record) r).pivotType()));
	}

	private void printEvent(String identifier, Collection<SoccerEvent> collection) {
		collection.stream().forEach(e -> {
			String keys = e.eventStates().stream().map(s -> ((SoccerEventState) s).partitionKey())
					.collect(Collectors.toList()).toString();
			log.info(this.identifier + " " + identifier + " " + e.matchId() + "_" + e.id() + "_" + keys);

		});
	}

	private void printMatch(String identifier, Collection<SoccerMatch> collection) {
		for (SoccerMatch match : collection) {
	       // System.out.println("push mode: " + match.host() + ":" + match.guest());
	    }
		collection.stream().forEach(m -> log.info(this.identifier + " " + identifier + " " + ((SoccerMatch) m).id()+ " " + convertEpochToReadable(((SoccerMatch) m).startTime())));
	}

}
