#pragma once

#include <string>
#include <vector>
#include <pugixml.hpp>
#include "opml_item.hpp"
#include "utils.hpp"

using namespace pugi;

/**
* Represents a collection of feeds, typically exported from a feed reader.
*
* Upon construction it will try its best to parse useful information out of
* the provided file.
*
* In case some value cannot be found, it will just contain an empty string.
*/
class Opml {
private:
    xml_document doc;
    xml_node body;

    std::string path;
    bool essentials_only{false};
    std::vector<OpmlItem> items;

    /**
    * Verifies if the file is a valid opml.
    */
    bool verify();

    /**
    * Entry point of the class, parses all the relevant content. Called by
    * the constructor.
    */
    void parse();

    void parse_node_children(
        xml_node node,
        std::vector<std::string> additional_categories={}
    );

public:

    /**
    * Constructs the Opml object from a valid OPML file path.
    * It will also automatically construct a vector of OpmlItem objects
    * representing the various feeds found in the collection.
    * 
    * @param path a valid file path to an RSS or Atom XML file.
    * @param essentials_only can optionally be set to true to just parse the
    *        feed url and the categories list; this can be done if the other
    *        values are not needed and can result in a small performance boost.
    *        This option will be passed to the constructor of OpmlItem.
    */
    Opml(
            std::string path, bool essentials_only=false
    ) : path{path}, essentials_only{essentials_only} {
        parse();
    }

    /**
    * Retrieve the OpmlItem objects that have been parsed.
    */
    std::vector<OpmlItem> get_items() { return items; }

    /**
    * Represents the Opml object (itself) as a json, returned as a string.
    */
    std::string to_json();
};
