#include "opml.hpp"


bool Opml::verify() {
    std::string root_name = doc.document_element().name();
    SynDomUtils::lower(root_name);
    return root_name == "opml";
}

void Opml::parse() {
    xml_parse_result res = doc.load_file(path.c_str());
    if (!res) {
        throw std::runtime_error("Error parsing XML file: "+path);
    }
    if (!verify()) {
        throw std::runtime_error(
            "Error: the XML file provided is not an OPML: "+path
        );
    }

    body = doc.document_element().child("body");
    if (!body) {
        throw std::runtime_error(
            "Error: the XML file provided is not an OPML (missing body): "
            + path
        );
    }

    parse_node_children(body);
}

void Opml::parse_node_children(
    xml_node node,
    std::vector<std::string> additional_categories
) {
    for (xml_node outline: node.children("outline")) {
        OpmlItem oi = OpmlItem(
            outline, essentials_only, additional_categories
        );
        if (!outline.children("outline").empty()) {
            std::string title = oi.get_title();
            std::vector<std::string> ac = additional_categories;
            if (title.empty()) title = oi.get_text();
            if (!title.empty()) ac.push_back(title);
            parse_node_children(outline, ac);
        }
        else if (oi.get_feed_url().empty()) {
            continue;
        }
        else {
            items.push_back(oi);
        }
    }
}

std::string Opml::to_json() {
    std::string res = "\n{\n"
        "    \"items\": [\n";
        for (auto i: items) {
            res += i.to_json() + ",\n";
        }
        res = res.substr(0, res.size()-2) + "\n";
        res += "    ]\n}\n";
    return res;
}
