package com.commafeed.backend.feeds;

import java.io.StringReader;
import java.util.List;

import javax.ejb.Asynchronous;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.commafeed.backend.cache.CacheService;
import com.commafeed.backend.dao.FeedCategoryDAO;
import com.commafeed.backend.model.FeedCategory;
import com.commafeed.backend.model.User;
import com.commafeed.backend.services.FeedSubscriptionService;
import com.commafeed.backend.services.FeedSubscriptionService.FeedSubscriptionException;
import com.sun.syndication.feed.opml.Opml;
import com.sun.syndication.feed.opml.Outline;
import com.sun.syndication.io.WireFeedInput;

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class OPMLImporter {

	private static Logger log = LoggerFactory.getLogger(OPMLImporter.class);

	@Inject
	FeedSubscriptionService feedSubscriptionService;

	@Inject
	FeedCategoryDAO feedCategoryDAO;

	@Inject
	CacheService cache;

	@SuppressWarnings("unchecked")
	@Asynchronous
	public void importOpml(User user, String xml) {

		WireFeedInput input = new WireFeedInput();
		try {
			Opml feed = (Opml) input.build(new StringReader(xml));
			List<Outline> outlines = (List<Outline>) feed.getOutlines();
			for (Outline outline : outlines) {
				handleOutline(user, outline, null);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}

	}

	@SuppressWarnings("unchecked")
	private void handleOutline(User user, Outline outline, FeedCategory parent) {

		if (StringUtils.isEmpty(outline.getType())) {
			FeedCategory category = feedCategoryDAO.findByName(user,
					outline.getText(), parent);
			if (category == null) {
				category = new FeedCategory();
				category.setName(FeedUtils.truncate(outline.getText(), 128));
				if (StringUtils.isBlank(category.getName())) {
					category.setName("Unnamed category");
				}
				category.setParent(parent);
				category.setUser(user);
				feedCategoryDAO.saveOrUpdate(category);
			}

			List<Outline> children = outline.getChildren();
			for (Outline child : children) {
				handleOutline(user, child, category);
			}
		} else {
			String title = outline.getText();
			if (StringUtils.isBlank(title)) {
				title = "Unnamed subscription";
			}
			// make sure we continue with the import process even a feed failed
			try {
				feedSubscriptionService.subscribe(user, outline.getXmlUrl(), title,
						parent);

			} catch (FeedSubscriptionException e) {
				throw e;
			} catch (Exception e) {
				log.error("error while importing {}: {}", outline.getXmlUrl(), e.getMessage());
			}
		}
		cache.invalidateUserData(user);
	}
}

@@ -1795,71 +1795,41 @@
 %0A%09%09%09
-FeedCategory category = feedCategoryDAO.findByName(user,%0D%0A%09%09%09%09%09
+String name = FeedUtils.truncate(
 outl
@@ -1843,22 +1843,19 @@
 Text(), 
-parent
+128
 );%0D%0A%09%09%09i
@@ -1857,24 +1857,20 @@
 %0A%09%09%09if (
-category
+name
  == null
@@ -1882,160 +1882,297 @@
 %09%09%09%09
-category = new FeedCategory();%0D%0A%09%09%09%09category.setName(FeedUtils.truncate(outline.getText(), 128));%0D%0A%09%09%09%09if (StringUtils.isBlank(category.getName())) %7B
+name = FeedUtils.truncate(outline.getTitle(), 128);%0D%0A%09%09%09%7D%0D%0A%09%09%09FeedCategory category = feedCategoryDAO.findByName(user, name,%0D%0A%09%09%09%09%09parent);%0D%0A%09%09%09if (category == null) %7B%0D%0A%09%09%09%09if (StringUtils.isBlank(name)) %7B%0D%0A%09%09%09%09%09name = %22Unnamed category%22;%0D%0A%09%09%09%09%7D%0D%0A%09%09%09%09%0D%0A%09%09%09%09category = new FeedCategory();
 %0D%0A
-%09
 %09%09%09%09
@@ -2192,35 +2192,14 @@
 ame(
-%22Un
 name
-d category%22);%0D%0A%09%09%09%09%7D
+);
 %0D%0A%09%09
@@ -2475,34 +2475,145 @@
 ing 
-title = outline.getText();
+name = FeedUtils.truncate(outline.getText(), 128);%0D%0A%09%09%09if (name == null) %7B%0D%0A%09%09%09%09name = FeedUtils.truncate(outline.getTitle(), 128);%0D%0A%09%09%09%7D
 %0D%0A%09%09
@@ -2637,20 +2637,19 @@
 isBlank(
-titl
+nam
 e)) %7B%0D%0A%09
@@ -2651,20 +2651,19 @@
  %7B%0D%0A%09%09%09%09
-titl
+nam
 e = %22Unn
@@ -2839,23 +2839,16 @@
 l(),
- title,
 %0D%0A%09%09%09%09%09%09
 pare
@@ -2839,24 +2839,30 @@
 l(),%0D%0A%09%09%09%09%09%09
+name, 
 parent);%0D%0A%0D%0A
@@ -2859,18 +2859,16 @@
 rent);%0D%0A
-%0D%0A
 %09%09%09%7D cat
@@ -3011,17 +3011,24 @@
 mlUrl(),
- 
+%0D%0A%09%09%09%09%09%09
 e.getMes

use title if text is empty (fix #419)