#include "tree.h"
#include "node.h"
#include "bulk_operations.h"
#include "zero_context_batch.h"
#include <cstring>
#include <algorithm>

namespace cutysoup {

Tree::Tree(const std::string& html) {
    output_ = gumbo_parse(html.c_str());
    if (output_ && output_->root) {
        root_node_ = std::make_shared<Node>(output_->root, this);
        node_cache_[output_->root] = root_node_;
        
        // Initialize bulk operations and build indices for ultra-fast searches
        bulk_ops_ = std::make_unique<BulkOperations>(this);
        bulk_ops_->build_indices(output_->root);
        
        // Initialize zero-context batch operations for ultimate performance
        zero_context_ = std::make_unique<ZeroContextBatch>(this);
    }
}

Tree::~Tree() {
    if (output_) {
        gumbo_destroy_output(&kGumboDefaultOptions, output_);
    }
}

std::shared_ptr<Node> Tree::get_root() const {
    return root_node_;
}

std::shared_ptr<Node> Tree::get_or_create_node(GumboNode* gumbo_node) const {
    if (!gumbo_node) {
        return nullptr;
    }

    std::lock_guard<std::mutex> lock(node_cache_mutex_);

    auto it = node_cache_.find(gumbo_node);
    if (it != node_cache_.end()) {
        std::shared_ptr<Node> cached = it->second.lock();
        if (cached) {
            return cached;
        }
    }

    std::shared_ptr<Node> node = std::make_shared<Node>(gumbo_node, this);
    node_cache_[gumbo_node] = node;
    return node;
}

std::shared_ptr<Node> Tree::create_element(const std::string& tag_name, 
                                          const std::map<std::string, std::string>& attributes) {
    (void)tag_name;
    (void)attributes;
    return nullptr;
}

GumboNode* Tree::create_gumbo_element(const std::string& tag_name, 
                                     const std::map<std::string, std::string>& attributes) {
    (void)tag_name;
    (void)attributes;
    return nullptr;
}

//==============================================================================
// Advanced Indexing Methods (delegated to BulkOperations)
//==============================================================================

std::vector<std::shared_ptr<Node>> Tree::find_by_attribute(const std::string& attr_name, const std::string& value) {
    if (bulk_ops_) {
        return bulk_ops_->find_by_attribute(attr_name, value);
    }
    return {};
}

std::vector<std::shared_ptr<Node>> Tree::find_by_text_content(const std::string& text) {
    if (bulk_ops_) {
        return bulk_ops_->find_by_text_content(text);
    }
    return {};
}

std::shared_ptr<Node> Tree::get_nth_element(size_t index) {
    if (bulk_ops_) {
        return bulk_ops_->get_nth_element(index);
    }
    return nullptr;
}

double Tree::get_index_build_time() const {
    if (bulk_ops_) {
        return bulk_ops_->get_index_build_time();
    }
    return 0.0;
}

size_t Tree::get_indexed_element_count() const {
    if (bulk_ops_) {
        return bulk_ops_->get_indexed_element_count();
    }
    return 0;
}

} // namespace cutysoup
