#pragma once

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

using namespace pugi;

/**
* Represents a single feed extracted from an OPML file.
*
* Typically you won't need to manually initialzie OpmlItem objects, you can
* instead create an Opml object and extract its OpmlItems using
* Opml::get_items().
*
* In case some value cannot be found, it will just contain an empty string.
*/
class OpmlItem {
private:
    xml_node item_node;
    bool essentials_only{false};
    std::string title;
    std::string description;
    std::string url;
    std::string feed_url;

    std::vector<std::string> categories{};
    std::vector<std::string> additional_categories{};

    std::string type;
    std::string language;

    /**
    * Entry point of the class, parses all the relevant content. Called by
    * the constructor.
    */
    void parse();
public:
    /**
    * Constructs the OpmlItem object from a `pugi::xml_node` representing an
    * item in an OPML file.
    * 
    * @param item_node a `pugi::xml_node` object representing an item inside an
    *        OPML body.
    * @param essentials_only can be optionally 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.
    */
    OpmlItem(
            xml_node item_node, bool essentials_only=false,
            std::vector<std::string> additional_categories={}
    ) : item_node{item_node}, essentials_only{essentials_only},
        additional_categories{additional_categories} {
        parse();
    }

    /**
    * Not applicable for a valid OpmlItem, gets the value of the text attribute
    * in case the current outline is a container for other outlines.
    */
    std::string get_text();

    std::string get_title() { return title; }
    std::string get_description() { return description; }
    std::string get_url() { return url; }
    std::string get_feed_url() { return feed_url; }
    std::vector<std::string> get_categories() { return categories; }
    std::string get_type() { return type; }
    std::string get_language() { return language; }

    std::string to_json();
};
