package org.apache.tika.parser.xml;

import java.util.ArrayList;
import java.util.List;

import org.apache.tika.metadata.AndroidContact;
import org.apache.tika.metadata.Metadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

public class ContactHandler extends DefaultHandler {
	
	private static final Logger logger = LoggerFactory.getLogger(ContactHandler.class);

	private ContentHandler handler;
	private Metadata metadata;
	private StringBuilder builder = new StringBuilder();
	
	private List<Contact> contactList = new ArrayList<Contact>();
	private Contact contact;

	public ContactHandler(ContentHandler handler, Metadata metadata) {
		super();
		this.handler = handler;
		this.metadata = metadata;
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		if (builder != null) {
			for (int i = start; i < start + length; i++) {
				builder.append(ch[i]);
			}
		}
	}

	@Override
	public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
		builder = new StringBuilder();
    	if (qName.equals("contact")) {
    		contact = new Contact();
    		String idStr = atts.getValue("id");
    		if (idStr != null && !idStr.isEmpty()) {
    			this.contact.setId(Integer.parseInt(idStr));
    		}
    	}
	}
	
	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.startDocument();
		
		logger.info("Starting to parse android contacts...");
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		
		String key = qName;
		
		if (key.equals("name")) {
			this.contact.setName(builder.toString());
    		// we use our own metadata instead of mapping to an existing ones
    		metadata.set(AndroidContact.NAME, builder.toString());
    		return;
    	}
		
		if (key.equals("address")) {
    		this.contact.setAddress(builder.toString());
    		metadata.set(AndroidContact.ADDRESS, builder.toString());
    		return;
    	}
		
		if (key.equals("phone")) {
			this.contact.setPhone(builder.toString());
    		metadata.set(AndroidContact.PHONE, builder.toString());
    		return;
    	}
		
		if (key.equals("url")) {
    		this.contact.setUrl(builder.toString());
    		metadata.set(AndroidContact.URL, builder.toString());
    		return;
    	}
		
		if (key.equals("email")) {
			// TODO: check email format?
    		this.contact.setEmail(builder.toString());
    		metadata.set(AndroidContact.EMAIL, builder.toString());
    		return;
    	}
    	
    	if (key.equals("contact")) {
    		contactList.add(this.contact);
    	}
	}
	
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
		
		logger.info("Successfully parsed "+contactList.size()+" contacts");
	}
	
	@Override
	public void error(SAXParseException e) throws SAXException {
		// TODO Auto-generated method stub
		super.error(e);
		
		logger.error("",e);
	}

	@Override
	public void fatalError(SAXParseException e) throws SAXException {
		// TODO Auto-generated method stub
		super.fatalError(e);
		
		logger.error("",e);
	}

	@Override
	public void warning(SAXParseException e) throws SAXException {
		// TODO Auto-generated method stub
		super.warning(e);
		
		logger.warn("",e);
	} 
	
	@Override
	public void ignorableWhitespace(char[] ch, int start, int length)
			throws SAXException {
		handler.ignorableWhitespace(ch, start, length);
	}
	
}
