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

import java.net.URI;
import java.net.URISyntaxException;

import org.apache.abdera.Abdera;
import org.apache.abdera.factory.Factory;
import org.apache.abdera.i18n.iri.IRI;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
import org.apache.abdera.util.Constants;

import be.ac.ulb.code.wit.ServiceConfiguration;
import be.ac.ulb.code.wit.contacts.Contact;
import be.ac.ulb.code.wit.contacts.Contacts;
import be.ac.ulb.code.wit.resources.ServicePaths;

/**
 * An atom serializer that generates atom entries representing
 * contact groups.
 * @author fpicalausa
 *
 */
public class GroupSerializer {
	private final Factory factory = Abdera.getInstance().getFactory();
	private final Contacts contacts;
	
	/**
	 * Construct a new GroupSerializer, using information
	 * from the given Contacts list.
	 * @param contacts The contacts list to be used.
	 */
	public GroupSerializer(final Contacts contacts) {
		super();
		this.contacts = contacts;
	}

	/**
	 * Creates an atom entry that represents a given group.
	 * @param group The group to be represented as an atom entry.
	 * @return an atom entry that represents a given group.
	 */
	private Entry makeGroupEntry (final String group) {
		if (!Contact.validGroupName(group)) {
			throw new NotFoundException();
		}
		
		final Entry entry = factory.newEntry();
		final String groupPath = ServicePaths.getURI(
				ServicePaths.GROUP, 
				"group", group);
		
		entry.setTitle(group);
		entry.setEdited(contacts.getLastModified());
		
		entry.setId(groupPath);
		entry.addLink(groupPath, AtomHelpers.Relations.EDIT);
		entry.addLink(groupPath, AtomHelpers.Relations.SELF);
		entry.setContent(new IRI(
				ServicePaths.getURI(ServicePaths.GROUP_CONTACTS, "group", group)), 
				Constants.FEED_MEDIA_TYPE);
		
		return entry;
	}
	
	/**
	 * Creates an atom feed that lists the contacts of a given group. 
	 * @return an atom feed that lists the contacts of a given group. 
	 */
	public Feed makeFeed() {
		final Feed groupsFeed = Abdera.getInstance().getFactory().newFeed();
		final be.ac.ulb.code.wit.contacts.Contacts contacts = ServiceConfiguration.getContacts();
		
		groupsFeed.setId(ServicePaths.getURI(ServicePaths.GROUPS));
		groupsFeed.setTitle("Contact Groups");
		groupsFeed.setUpdated(contacts.getLastModified());
		groupsFeed.addLink(ServicePaths.getURI(ServicePaths.GROUPS), "self");
		
		for (String group: contacts.getGroups()) {
			groupsFeed.addEntry(makeGroupEntry(group));
		}
		
		return groupsFeed;
	}

	/**
	 * Get the URI at which the specified group can be found.
	 * @param group The group for which the URI is to be retrieved.
	 * @return the URI at which the specified group can be found.
	 */
	public URI getURI(String group) {
		try {
			return new URI(ServicePaths.getURI(ServicePaths.GROUP,"group",group));
		} catch (URISyntaxException e) {
			//Should not happen because the URI are well know. Cannot recover from this
			throw new IllegalStateException(e);
		}
	}

	/**
	 * Creates an atom:entry String that represents a given group.
	 * @param group The group to be represented as an atom entry.
	 * @return an atom:entry String that represents a given group.
	 */
	public String makeEntry(String group) {
		return AtomHelpers.stringify(makeGroupEntry(group));
	}
}
