package eu.toldi.rss;

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

import javax.swing.tree.DefaultMutableTreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * Egy RSS hírcsatorna reprezentálására használt osztály.
 */
@XStreamAlias("feed")
public class Feed {
    /**
     * A hírcsatorna elérési útvonala
     */
    private URL link;
    /**
     * A hírcsatorna neve
     */
    private String name;
    /**
     * A hírcsatornához tartozó cikkek listája
     */
    @XStreamAlias("articleList")
    private List<Article> articleList = new ArrayList<>();;

    /**
     * A hírcsatorna nevének lekérése
     *
     * @return a hírcsatorna neve
     */
    public String getName() {
        return name;
    }

    /**
     * Hírcsatorna lézrehozása elérési útvonal alapján
     * @param url a hírcsatorna elérési útvonala
     * @throws IOException
     */
    public Feed(URL url) throws IOException {
        articleList = new ArrayList<>();
        link = url;
        updateFeed();
    }

    /**
     * Hírcsatorna létrehozása név alapján
     * @param name a hírcsatorna neve
     */
    public Feed(String name) {
        this.name = name;
    }

    /**
     * A hírcsatornán található cikkek számának lekérése
     * @return a hírcsatorna található cikkek száma
     */
    public int getArticleCount() {
        return articleList.size();
    }

    /**
     * Egy adott helyen található cikk lekérése
     * @param i a cikk indexe
     * @return Az i. helyen található cikk
     */
    public Article get(int i) {
        return articleList.get(i);
    }

    /**
     * Hírcsatorna frissítése.
     * Lekéri a hírcsatorna elérési útvonalán található összes új cikket és hozzáadja a cikkek listájához.
     * @throws IOException
     */
    public void updateFeed() throws IOException {
        URLConnection con = link.openConnection();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newDefaultInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(con.getInputStream());
            name = doc.getElementsByTagName("title").item(0).getTextContent();

            NodeList items = doc.getElementsByTagName("item");
            for (int i = 0; i < items.getLength(); i++) {
                Node article = items.item(i);
                Article a = new Article(article);
                addArticle(a);
            }
        } catch (ParserConfigurationException | SAXException e) {
            e.printStackTrace();
        }

    }

    /**
     * Hírcsatorna nevének beállítása
     * @param name a hírcsatorna új neve
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Megnézi hogy egy magadott cikk megtalálható-e a hírcsatornán
     * @param a a keresett cikk
     * @return logikai érték az alapján,hogy a megadott cikk meg lett-e találva
     * Megjegyzés:  Ez egy lineáris keresést hajt végre
     */
    public boolean hasAricle(Article a) {
        for (Article art : articleList) {
            if (art.getURL() != null && art.getURL().equals(a.getURL()))
                return true;
        }
        return false;
    }

    /**
     * Új cikk felvétele a listába.
     * @param a új cikk
     * Megjegyzés: cikket csak akkor veszi fel,ha az még nem található a listájában
     */
    public void addArticle(Article a) {
        if (!hasAricle(a))
            articleList.add(a);
    }

    /**
     * TreeNode készítése a hírcsatornáról
     * @return
     */
    public DefaultMutableTreeNode getTreeNode() {
        return new DefaultMutableTreeNode(this);
    }

    /**
     * Hírcsatorna elérési útvonalának lekérése
     * @return a hírcsatorna elérési útvonala
     */
    public String getLink() {
        return link.toString();
    }

    /**
     * A hírcsatornához tartozó cikkek listájának lekérése
     * @return A hírcsatorna tartozó cikkek listája
     */
    public List<Article> getArticleList() {
        return articleList;
    }

    @Override
    public String toString() {
        return name;
    }
}
