/*
 * FeedParser.vala
 * 
 * Main feed parser that detects and handles both RSS and Atom feeds
 */

public class RSSuper.FeedParser : Object {
    private RSSParser rss_parser;
    private AtomParser atom_parser;

    public FeedParser() {
        this.rss_parser = new RSSParser();
        this.atom_parser = new AtomParser();
    }

    public ParseResult parse(string xml_content, string url) {
        var type = detect_feed_type(xml_content);
        
        switch (type) {
            case FeedType.ATOM:
                return atom_parser.parse(xml_content, url);
            case FeedType.RSS_1_0:
            case FeedType.RSS_2_0:
            default:
                return rss_parser.parse(xml_content, url);
        }
    }

    public FeedType detect_feed_type(string xml_content) {
        Xml.Doc* doc = Xml.Parser.parse_doc(xml_content);
        if (doc == null) {
            return FeedType.UNKNOWN;
        }
        
        Xml.Node* root = doc->get_root_element();
        if (root == null) {
            delete doc;
            return FeedType.UNKNOWN;
        }
        
        string? name = root->name;
        
        if (name == "feed") {
            Xml.Ns* ns = root->ns;
            if (ns == null || ns->href == null || ns->href == "http://www.w3.org/2005/Atom") {
                delete doc;
                return FeedType.ATOM;
            }
        }
        
        if (name == "rss") {
            string? version = root->get_prop("version");
            delete doc;
            if (version == "2.0") {
                return FeedType.RSS_2_0;
            }
            if (version == "0.91" || version == "0.92") {
                return FeedType.RSS_2_0;
            }
            if (version == "1.0") {
                return FeedType.RSS_1_0;
            }
            return FeedType.RSS_2_0;
        }
        
        delete doc;
        
        if (name == "RDF") {
            return FeedType.RSS_1_0;
        }
        
        return FeedType.UNKNOWN;
    }

    public ParseResult parse_from_content_type(string xml_content, string url, string? content_type = null) {
        if (content_type != null) {
            var type = FeedType.from_string(content_type);
            if (type == FeedType.ATOM) {
                return atom_parser.parse(xml_content, url);
            }
            if (type == FeedType.RSS_1_0 || type == FeedType.RSS_2_0) {
                return rss_parser.parse(xml_content, url);
            }
        }
        
        return parse(xml_content, url);
    }
}
