package be.ac.ulb.code.wit.resources.serializers.atom;

import org.apache.abdera.Abdera;
import org.apache.abdera.factory.Factory;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;

import be.ac.ulb.code.wit.contacts.Contact;
import be.ac.ulb.code.wit.contacts.Contacts;
import be.ac.ulb.code.wit.contacts.Contacts.IdentifiedContact;
import be.ac.ulb.code.wit.resources.ServicePaths;
import be.ac.ulb.code.wit.resources.serializers.atom.AtomHelpers.Relations;
import be.ac.ulb.code.wit.resources.serializers.helpers.ContactSerializer;
import be.ac.ulb.code.wit.resources.serializers.helpers.NotFoundException;

public class AtomContactSerializer extends ContactSerializer {
	private final static Factory ABDERA_FACTORY = Abdera.getInstance().getFactory();
	
	public AtomContactSerializer(Contacts contacts, String group)
			throws NotFoundException {
		super(contacts, group);
	}

	/**
	 * Creates an atom entry representing a contact.
	 * @param identifiedContact The contact to be serialized as an atom entry.
	 * @param summary Whether only a summary of the information (to include into
	 * 				a feed) is to be generated.
	 * @return an atom entry representing the given contact.
	 */
	private Entry makeEntry(final IdentifiedContact identifiedContact, final boolean summary) {
		final Entry entry = ABDERA_FACTORY.newEntry();
		final Contact contact = identifiedContact.getContact();
		final String contactId = Integer.toString(identifiedContact.getContactId());

		entry.setTitle(contact.getDisplayName());
		entry.setEdited(contact.getLastModified());
		entry.setId(ServicePaths.getURI(ServicePaths.CONTACT,
			"contactid", contactId));
		entry.addLink(getContactURL(identifiedContact).toString(), Relations.EDIT);
		entry.addLink(getContactURL(identifiedContact).toString(), Relations.SELF);

		if (!summary) {
			entry.addExtension(AtomHelpers.createExtensionElement(
				AtomHelpers.ExtensionElements.CONTACT_FIRSTNAME,
				contact.getFirstName()));

			entry.addExtension(AtomHelpers.createExtensionElement(
				AtomHelpers.ExtensionElements.CONTACT_LASTNAME,
				contact.getLastName()));

			entry.addExtension(AtomHelpers.createExtensionElement(
				AtomHelpers.ExtensionElements.CONTACT_EMAIL,
				contact.getEmail()));

			for (String contactGroup: contacts.getContactGroups(identifiedContact)) {
				entry.addLink(ServicePaths.getURI(ServicePaths.GROUP,
						"group", contactGroup), AtomHelpers.Relations.GROUP);
			}
		}

		return entry;
	}
	
	/**
	 * Make a String representation of a contact, as an atom entry.
	 * @param contact The contact to be represented as an atom entry.
	 * @return a String representation of the given contact, as an atom entry.
	 */
	public String makeStringEntry(IdentifiedContact contact) {
		return AtomHelpers.stringify(makeEntry(contact, false));
	}

	
	/**
	 * Creates an atom entry representing a contact as part of a feed
	 */
	private Entry makeFeedEntry(IdentifiedContact contact) {
		return makeEntry(contact, true);
	}
	
	/**
	 * Generates an atom feed containing every contacts in the context group.
	 * @return an atom feed containing every contacts in the context group.
	 */
	public String makeFeed() {
		final Feed contactsFeed = Abdera.getInstance().getFactory().newFeed();
		String url;
		
		if (group == Contacts.GROUP_ALLCONTACTS) {
			url = ServicePaths.getURI(ServicePaths.CONTACTS); 
			contactsFeed.setTitle("Contacts List");
		}
		else {
			contactsFeed.setTitle("Contacts in group " + group);
			url = ServicePaths.getURI(ServicePaths.GROUP,
						"group", group);
		}
		
		contactsFeed.addLink(url, Relations.SELF);
		contactsFeed.setId(url);
		contactsFeed.setUpdated(contacts.getLastModified());
		
		for (IdentifiedContact contact: contacts.getContacts(group)) {
			contactsFeed.addEntry(makeFeedEntry(contact));
		}
		
		return AtomHelpers.stringify(contactsFeed);
	}
}
