package eu.toldi.rss;

import com.thoughtworks.xstream.XStream;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class FeedLoader {

    private FeedData data;


    private Feed getFeed(NodeList feedProperties) throws MalformedURLException {
        List<Article> articleList = new ArrayList<Article>();
        String url = null;
        for (int j = 1; j < feedProperties.getLength(); j+=2) {
            Node node = feedProperties.item(j);
            String tagName = node.getNodeName();


            switch (tagName){
                case "link":
                    url = node.getTextContent();
                    break;
                case "articleList":
                    NodeList articles = node.getChildNodes();
                    for (int k = 0; k < articles.getLength(); k++) {
                        Node article = articles.item(k);
                        Article a = new Article(article, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                        if(a.getURL() != null)
                            articleList.add(a);
                    }
            }
            if(url == null) return null;
        }
        Feed feed = new Feed(new URL(url));
        for (int k = 0; k < articleList.size(); k++) {
            feed.addArticle(articleList.get(k));
        }
        return feed;
    }

    public FeedData loadFeedData(String filename) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newDefaultInstance();
        data = new FeedData();

        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new File(filename));

            NodeList feeds = doc.getFirstChild().getChildNodes();
            for (int i = 1; i < feeds.getLength(); i=i+2) {
                if(feeds.item(i).getNodeName().equals("feed")) {
                    Feed feed = getFeed(feeds.item(i).getChildNodes());
                    if(feed != null)data.addFeed(feed);
                }else if (feeds.item(i).getNodeName().equals("feedGroup")){
                    NodeList feedGroupprops = feeds.item(i).getChildNodes();
                    String name = null;
                    FeedGroup fg = null;
                    int feedCounter = 0;
                    for (int j = 1; j < feedGroupprops.getLength(); j+=2) {
                        Node node = feedGroupprops.item(j);
                        String tagName = node.getNodeName();
                        switch (tagName){
                            case "name":
                                fg = new FeedGroup(node.getTextContent());
                                break;
                            case "feedList":
                                if(fg == null) continue;
                                NodeList feedList1 = node.getChildNodes();
                                for (int k = 1; k < feedList1.getLength(); k+=2) {
                                    Node f = feedList1.item(k);
                                    Feed feed = getFeed(f.getChildNodes());
                                    fg.addFeed(feed);
                                    feedCounter++;
                                }
                        }
                    }
                    if(fg != null && feedCounter != 0)
                        data.addFeed(fg);
                }else
                    System.out.println(feeds.item(i).getNodeName());
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }

        return data;
    }



    public void saveFeedData() {
        XStream xStream = new XStream();
        xStream.processAnnotations(Article.class);
        xStream.processAnnotations(Feed.class);
        xStream.processAnnotations(FeedGroup.class);
        xStream.omitField(FeedData.class, "articleList");
        xStream.omitField(javax.swing.event.EventListenerList.class, "listenerList");
        String xml = xStream.toXML(data.getFeeds());
        BufferedWriter writer;
        try {
            writer = new BufferedWriter(new FileWriter("feeds.xml"));
            writer.write(xml);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setData(FeedData data) {
        this.data = data;
    }
}
