import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.*;
import java.util.HashMap;

import Six.Sixp.Client.*;
import Six.Sixp.Client.Error;

public class DataListener implements IRequestEventListener {
	private ISession session;
	private ConcurrentLinkedQueue<ICommand> queue;
	private HashMap<Integer,RecordIdAndPrl> requestIdtoRecId = new HashMap<Integer,RecordIdAndPrl>();
	
	public DataListener(ISession s, ConcurrentLinkedQueue<ICommand> q) {
		session = s;
		queue = q;
	}

	@Override
	public void OnClearTable(IRequest request) {
		System.out.println("OnClearTable ReqId:" + request.getId());
	}

	@Override
	public void OnDestroyed(IRequest request) {
		System.out.println("OnClearTable ReqId:" + request.getId());		
	}

	@Override
	public void OnError(IRequest request, Error errorCode, String errorMessage) {
        System.out.println("OnError ReqId:" + request.getId() + " (" + errorCode + ") " + errorMessage);	
	}

	@Override
	public void OnFieldSetReceived(IRequest request, FieldInfoSet fieldset) {
        System.out.println("OnFieldsetReceived");
		
		for (FieldInfo i : fieldset.elements())
		{
			queue.add(new ColumnAdder(StripNonAlphaNumericFromName(request.getPrl()), i.GetName()));	
		}
	}

	@Override
	public void OnInitTable(IRequest request, int numRecords) {
        System.out.println("OnInitTable: Num records " + numRecords);
	}

	@Override
	public void OnRecordUpdate(IRequest request, Vector<Update> updates) {

		for (Update u : updates) {

			HashMap<String,Object> nameToValue = new HashMap<String,Object>();
			
			for (Field f : u.GetFields()) {
				
				nameToValue.put(f.GetFieldInfo().GetName(), f.GetValue());
				
				// To get the full news text a new request is created, this is only applicable to news queries /rt/news and /hist/news
				if (f.GetFieldInfo().GetFieldType() == FieldType.Link) {
					try {
						IRequest r = session.CreateRequest(f.GetValue().toString(), AcceptFormat.Text, false, this);
						r.ExecuteAsync();
						requestIdtoRecId.put(r.getId(), new RecordIdAndPrl(Long.toString(u.GetRecordId()), request.getPrl()));
					}
					catch (Exception ex) {
						System.out.println("Exception fetching news text: " + ex.toString());
					}
				}
			}
			queue.add(new RecordUpdater(StripNonAlphaNumericFromName(request.getPrl()), Long.toString(u.GetRecordId()), u.GetKey(), nameToValue));
		}
	}

	@Override
	public void OnTableFilled(IRequest request) {
		System.out.println("OnTableFilled ReqId:" + request.getId());
	}

	@Override
	public void OnText(IRequest request, String text) {
		Integer requestId = request.getId();
		
		String recordId = requestIdtoRecId.get(requestId).getRecordId();
		String prl = requestIdtoRecId.get(requestId).getPrl();
		
		queue.add(new NewsTextUpdater(StripNonAlphaNumericFromName(prl), recordId, text));
	}
	
	private String StripNonAlphaNumericFromName(String name)
	{
		String ret = name.replaceAll("[^A-Za-z0-9]", "");
		return ret.replaceAll("\\s+","");
	}
	
	private class RecordIdAndPrl
	{
		private final String recordId;
		private final String prl;
		
		public RecordIdAndPrl(String r, String p)
		{
			recordId = r;
			prl = p;
		}
		
		public String getRecordId()
		{
			return recordId;
		}
		
		public String getPrl()
		{
			return prl;
		}
	
	}
}
