package com.commafeed.backend.services;

import java.util.List;

import javax.ejb.Stateless;
import javax.inject.Inject;

import com.commafeed.backend.dao.FeedEntryDAO;
import com.commafeed.backend.dao.FeedEntryStatusDAO;
import com.commafeed.backend.dao.FeedSubscriptionDAO;
import com.commafeed.backend.feeds.FeedRefreshTaskGiver;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedCategory;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.model.User;
import com.google.api.client.util.Lists;

@Stateless
public class FeedSubscriptionService {

	@Inject
	FeedService feedService;

	@Inject
	FeedEntryDAO feedEntryDAO;

	@Inject
	FeedEntryStatusDAO feedEntryStatusDAO;

	@Inject
	FeedSubscriptionDAO feedSubscriptionDAO;

	@Inject
	ApplicationSettingsService applicationSettingsService;

	@Inject
	FeedRefreshTaskGiver taskGiver;

	public Feed subscribe(User user, String url, String title,
			FeedCategory category) {

		final String pubUrl = applicationSettingsService.get().getPublicUrl();
		if (pubUrl == null) {
			throw new RuntimeException("Public URL of this CommaFeed is unset");
		}
		if (url.startsWith(pubUrl)) {
			throw new RuntimeException(
					"Could not subscribe to a feed from this CommaFeed instance");
		}

		Feed feed = feedService.findOrCreate(url);

		FeedSubscription sub = feedSubscriptionDAO.findByFeed(user, feed);
		boolean newSubscription = false;
		if (sub == null) {
			sub = new FeedSubscription();
			sub.setFeed(feed);
			sub.setUser(user);
			newSubscription = true;
		}
		sub.setCategory(category);
		sub.setTitle(title.substring(0, Math.min(128, title.length())));
		feedSubscriptionDAO.saveOrUpdate(sub);

		if (newSubscription) {
			List<FeedEntryStatus> statuses = Lists.newArrayList();
			List<FeedEntry> allEntries = feedEntryDAO.findByFeed(feed, 0, 10);
			for (FeedEntry entry : allEntries) {
				FeedEntryStatus status = new FeedEntryStatus();
				status.setEntry(entry);
				status.setRead(false);
				status.setSubscription(sub);
				statuses.add(status);
			}
			feedEntryStatusDAO.save(statuses);
		}
		taskGiver.add(feed);
		return feed;
	}
}

@@ -87,24 +87,64 @@
 Stateless;%0D%0A
+import javax.ejb.ApplicationException;%0D%0A
 import javax
@@ -156,24 +156,24 @@
 ct.Inject;%0D%0A
-
 %0D%0Aimport com
@@ -760,16 +760,183 @@
 rvice %7B%0D
+%0A%09@ApplicationException%0D%0A%09public class FeedSubscriptionException extends RuntimeException %7B%0D%0A%09%09public FeedSubscriptionException(String msg) %7B%0D%0A%09%09%09super(msg);%0D%0A%09%09%7D%0D%0A%09%7D%0D
 %0A%0D%0A%09@Inj
@@ -1429,39 +1429,48 @@
 %7B%0D%0A%09%09%09throw new 
-Runtime
+FeedSubscription
 Exception(%22Publi
@@ -1463,16 +1463,22 @@
 ception(
+%0D%0A%09%09%09%09
 %22Public 

Make the error message prettier by avoiding a nested exception.