#pragma once
#include "includes.cpp"

#ifdef NO_CURL

inline i64 py_get_url_size(const str& url) {
    py::gil_scoped_acquire acquire;
    try {
        py::module_ urllib_request = py::module_::import("urllib.request");
        py::module_ urllib_error = py::module_::import("urllib.error");
        py::object Request = urllib_request.attr("Request");
        
        py::object request = Request(url, py::none(), py::dict(), py::none(), py::none(), "HEAD");
        py::object response = urllib_request.attr("urlopen")(request, py::arg("timeout") = 20);
        
        py::object headers = response.attr("headers");
        py::object content_length = headers.attr("get")("Content-Length");
        
        if (content_length.is_none()) {
            throw std::runtime_error("Content-Length header not available for: " + url);
        }
        
        return py::cast<i64>(py::int_(content_length));
    } catch (py::error_already_set& e) {
        // Clear the python error and translate to C++ exception
        std::string err_msg = e.what();
        e.restore(); // Optional: clears the error indicator in Python
        throw std::runtime_error("Python URL size error (" + url + "): " + err_msg);
    }
}

inline std::vector<u8> py_read_url_all(const str& url) {
    py::gil_scoped_acquire acquire;
    try {
        py::module_ urllib_request = py::module_::import("urllib.request");
        
        py::object response = urllib_request.attr("urlopen")(url, py::arg("timeout") = 20);
        py::bytes content = response.attr("read")();
        
        std::string_view sv = content.cast<std::string_view>();
        return std::vector<u8>(sv.begin(), sv.end());
    } catch (py::error_already_set& e) {
        throw std::runtime_error("Python URL read error: " + std::string(e.what()));
    }
}

inline std::vector<u8> py_read_url(const str& url, i64 size, i64 offset) {
    py::gil_scoped_acquire acquire;
    try {
        py::module_ urllib_request = py::module_::import("urllib.request");
        py::object Request = urllib_request.attr("Request");
        
        py::object request = Request(url);
        std::string range_header = "bytes=" + std::to_string(offset) + "-" + std::to_string(offset + size - 1);
        request.attr("add_header")("Range", range_header);
        
        // Added timeout
        py::object response = urllib_request.attr("urlopen")(request, py::arg("timeout") = 20);
        py::bytes content = response.attr("read")();
        
        std::string_view sv = content.cast<std::string_view>();
        return std::vector<u8>(sv.begin(), sv.end());
    } catch (py::error_already_set& e) {
        throw std::runtime_error("Python partial URL read error: " + std::string(e.what()));
    }
}

#endif
