/**
 * OpenAPI Petstore
 * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
 *
 * The version of the OpenAPI document: 1.0.0
 * 
 *
 * NOTE: This class is auto generated by OpenAPI-Generator 7.0.0-SNAPSHOT.
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */


#include <corvusoft/restbed/byte.hpp>
#include <corvusoft/restbed/string.hpp>
#include <corvusoft/restbed/settings.hpp>
#include <corvusoft/restbed/request.hpp>
#include <corvusoft/restbed/uri.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

#include "PetApi.h"

namespace org {
namespace openapitools {
namespace server {
namespace api {

using namespace org::openapitools::server::model;

namespace {
[[maybe_unused]]
std::string selectPreferredContentType(const std::vector<std::string>& contentTypes) {
    if (contentTypes.size() == 0) {
        return "application/json";
    }

    if (contentTypes.size() == 1) {
        return contentTypes.at(0);
    }

    static const std::array<std::string, 2> preferredTypes = {"json", "xml"};
    for (const auto& preferredType: preferredTypes) {
        const auto ret = std::find_if(contentTypes.cbegin(),
        contentTypes.cend(),
        [preferredType](const std::string& str) {
            return str.find(preferredType) != std::string::npos;});
        if (ret != contentTypes.cend()) {
            return *ret;
        }
    }

    return contentTypes.at(0);
}
}

PetApiException::PetApiException(int status_code, std::string what)
  : m_status(status_code),
    m_what(what)
{

}
int PetApiException::getStatus() const
{
    return m_status;
}
const char* PetApiException::what() const noexcept
{
    return m_what.c_str();
}


template<class MODEL_T>
MODEL_T extractJsonModelBodyParam(const std::string& bodyContent)
{
    std::stringstream sstream(bodyContent);
    boost::property_tree::ptree pt;
    boost::property_tree::json_parser::read_json(sstream, pt);

    auto model = MODEL_T(pt);
    return model;
}

template<class MODEL_T>
std::vector<MODEL_T> extractJsonArrayBodyParam(const std::string& bodyContent)
{
    std::stringstream sstream(bodyContent);
    boost::property_tree::ptree pt;
    boost::property_tree::json_parser::read_json(sstream, pt);

    auto arrayRet = std::vector<MODEL_T>();
    for (const auto& child: pt) {
        arrayRet.emplace_back(MODEL_T(child.second));
    }
    return arrayRet;
}

template <class KEY_T, class VAL_T>
std::string convertMapResponse(const std::map<KEY_T, VAL_T>& map)
{
    boost::property_tree::ptree pt;
    for(const auto &kv: map) {
    pt.push_back(boost::property_tree::ptree::value_type(
        boost::lexical_cast<std::string>(kv.first),
        boost::property_tree::ptree(
        boost::lexical_cast<std::string>(kv.second))));
    }
    std::stringstream sstream;
    write_json(sstream, pt);
    std::string result = sstream.str();
    return result;
}

namespace PetApiResources {
PetResource::PetResource(const std::string& context /* = "/v2" */)
{
	this->set_path(context + "/pet");
	this->set_method_handler("POST",
		std::bind(&PetResource::handler_POST_internal, this,
			std::placeholders::_1));
	this->set_method_handler("PUT",
		std::bind(&PetResource::handler_PUT_internal, this,
			std::placeholders::_1));
}

std::pair<int, std::string> PetResource::handlePetApiException(const PetApiException& e)
{
    return std::make_pair<int, std::string>(e.getStatus(), e.what());
}

std::pair<int, std::string> PetResource::handleStdException(const std::exception& e)
{
    return std::make_pair<int, std::string>(500, e.what());
}

std::pair<int, std::string> PetResource::handleUnspecifiedException()
{
    return std::make_pair<int, std::string>(500, "Unknown exception occurred");
}

void PetResource::setResponseHeader(const std::shared_ptr<restbed::Session>& session, const std::string& header)
{
    session->set_header(header, "");
}

void PetResource::returnResponse(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result, std::multimap<std::string, std::string>& responseHeaders)
{
    responseHeaders.insert(std::make_pair("Connection", "close"));
    session->close(status, result, responseHeaders);
}

void PetResource::defaultSessionClose(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result)
{
    session->close(status, result, { {"Connection", "close"} });
}

void PetResource::handler_POST_internal(const std::shared_ptr<restbed::Session> session)
{
    const auto request = session->get_request();
    // body params or form params here from the body content string
    std::string bodyContent = extractBodyContent(session);
    auto pet = extractJsonModelBodyParam<Pet>(bodyContent);
    
    int status_code = 500;
    std::string result = "";
    
    try {
        status_code =
            handler_POST(pet);
    }
    catch(const PetApiException& e) {
        std::tie(status_code, result) = handlePetApiException(e);
    }
    catch(const std::exception& e) {
        std::tie(status_code, result) = handleStdException(e);
    }
    catch(...) {
        std::tie(status_code, result) = handleUnspecifiedException();
    }
    
    std::multimap< std::string, std::string > responseHeaders {};
    static const std::vector<std::string> contentTypes{
        "application/json"
    };
    static const std::string acceptTypes{
        "application/json, application/xml, "
    };
    
    if (status_code == 200) {
        responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
        if (!acceptTypes.empty()) {
            responseHeaders.insert(std::make_pair("Accept", acceptTypes));
        }
    
        returnResponse(session, 200, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 405) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Invalid input";
    
        returnResponse(session, 405, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    defaultSessionClose(session, status_code, result);
}

// x-extension
void PetResource::handler_PUT_internal(const std::shared_ptr<restbed::Session> session) {
    const auto request = session->get_request();
    // body params or form params here from the body content string
    std::string bodyContent = extractBodyContent(session);
    auto pet = extractJsonModelBodyParam<Pet>(bodyContent);
    
    int status_code = 500;
    std::string result = "";
    
    try {
        status_code =
            handler_PUT(pet);
    }
    catch(const PetApiException& e) {
        std::tie(status_code, result) = handlePetApiException(e);
    }
    catch(const std::exception& e) {
        std::tie(status_code, result) = handleStdException(e);
    }
    catch(...) {
        std::tie(status_code, result) = handleUnspecifiedException();
    }
    
    std::multimap< std::string, std::string > responseHeaders {};
    static const std::vector<std::string> contentTypes{
        "application/json"
    };
    static const std::string acceptTypes{
        "application/json, application/xml, "
    };
    
    if (status_code == 200) {
        responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
        if (!acceptTypes.empty()) {
            responseHeaders.insert(std::make_pair("Accept", acceptTypes));
        }
    
        returnResponse(session, 200, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 400) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Invalid ID supplied";
    
        returnResponse(session, 400, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 404) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Pet not found";
    
        returnResponse(session, 404, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 405) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Validation exception";
    
        returnResponse(session, 405, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    defaultSessionClose(session, status_code, result);
}

int PetResource::handler_POST(
        Pet & pet)
{
    return handler_POST_func(pet);
}

int PetResource::handler_PUT(
    Pet & pet)
{
    return handler_PUT_func(pet);
}

std::string PetResource::extractBodyContent(const std::shared_ptr<restbed::Session>& session) {
  const auto request = session->get_request();
  int content_length = request->get_header("Content-Length", 0);
  std::string bodyContent;
  session->fetch(content_length,
                 [&bodyContent](const std::shared_ptr<restbed::Session> session,
                                const restbed::Bytes &body) {
                   bodyContent = restbed::String::format(
                       "%.*s\n", (int)body.size(), body.data());
                 });
  return bodyContent;
}

std::string PetResource::extractFormParamsFromBody(const std::string& paramName, const std::string& body) {
    const auto uri = restbed::Uri("urlencoded?" + body, true);
    const auto params = uri.get_query_parameters();
    const auto result = params.find(paramName);
    if (result != params.cend()) {
        return result->second;
    }
    return "";
}
PetPetIdResource::PetPetIdResource(const std::string& context /* = "/v2" */)
{
	this->set_path(context + "/pet/{petId: .*}");
	this->set_method_handler("DELETE",
		std::bind(&PetPetIdResource::handler_DELETE_internal, this,
			std::placeholders::_1));
	this->set_method_handler("GET",
		std::bind(&PetPetIdResource::handler_GET_internal, this,
			std::placeholders::_1));
	this->set_method_handler("POST",
		std::bind(&PetPetIdResource::handler_POST_internal, this,
			std::placeholders::_1));
}

std::pair<int, std::string> PetPetIdResource::handlePetApiException(const PetApiException& e)
{
    return std::make_pair<int, std::string>(e.getStatus(), e.what());
}

std::pair<int, std::string> PetPetIdResource::handleStdException(const std::exception& e)
{
    return std::make_pair<int, std::string>(500, e.what());
}

std::pair<int, std::string> PetPetIdResource::handleUnspecifiedException()
{
    return std::make_pair<int, std::string>(500, "Unknown exception occurred");
}

void PetPetIdResource::setResponseHeader(const std::shared_ptr<restbed::Session>& session, const std::string& header)
{
    session->set_header(header, "");
}

void PetPetIdResource::returnResponse(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result, std::multimap<std::string, std::string>& responseHeaders)
{
    responseHeaders.insert(std::make_pair("Connection", "close"));
    session->close(status, result, responseHeaders);
}

void PetPetIdResource::defaultSessionClose(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result)
{
    session->close(status, result, { {"Connection", "close"} });
}

void PetPetIdResource::handler_DELETE_internal(const std::shared_ptr<restbed::Session> session)
{
    const auto request = session->get_request();
    // Getting the path params
    int64_t petId = request->get_path_parameter("petId", 0L);
    // Getting the headers
    std::string apiKey = request->get_header("api_key", "");
    
    int status_code = 500;
    std::string result = "";
    
    try {
        status_code =
            handler_DELETE(petId, apiKey);
    }
    catch(const PetApiException& e) {
        std::tie(status_code, result) = handlePetApiException(e);
    }
    catch(const std::exception& e) {
        std::tie(status_code, result) = handleStdException(e);
    }
    catch(...) {
        std::tie(status_code, result) = handleUnspecifiedException();
    }
    
    std::multimap< std::string, std::string > responseHeaders {};
    static const std::vector<std::string> contentTypes{
        "application/json"
    };
    static const std::string acceptTypes{
    };
    
    if (status_code == 200) {
        responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
        if (!acceptTypes.empty()) {
            responseHeaders.insert(std::make_pair("Accept", acceptTypes));
        }
    
        returnResponse(session, 200, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 400) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Invalid pet value";
    
        returnResponse(session, 400, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    defaultSessionClose(session, status_code, result);
}

// x-extension
void PetPetIdResource::handler_GET_internal(const std::shared_ptr<restbed::Session> session) {
    const auto request = session->get_request();
    // Getting the path params
    int64_t petId = request->get_path_parameter("petId", 0L);
    
    int status_code = 500;
    Pet resultObject = Pet{};
    std::string result = "";
    
    try {
        std::tie(status_code, resultObject) =
            handler_GET(petId);
    }
    catch(const PetApiException& e) {
        std::tie(status_code, result) = handlePetApiException(e);
    }
    catch(const std::exception& e) {
        std::tie(status_code, result) = handleStdException(e);
    }
    catch(...) {
        std::tie(status_code, result) = handleUnspecifiedException();
    }
    
    std::multimap< std::string, std::string > responseHeaders {};
    static const std::vector<std::string> contentTypes{
        "application/xml","application/json",
    };
    static const std::string acceptTypes{
    };
    
    if (status_code == 200) {
        responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
        if (!acceptTypes.empty()) {
            responseHeaders.insert(std::make_pair("Accept", acceptTypes));
        }
    
        result = resultObject.toJsonString();
        returnResponse(session, 200, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 400) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Invalid ID supplied";
    
        returnResponse(session, 400, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 404) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Pet not found";
    
        returnResponse(session, 404, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    defaultSessionClose(session, status_code, result);
}
// x-extension
void PetPetIdResource::handler_POST_internal(const std::shared_ptr<restbed::Session> session) {
    const auto request = session->get_request();
    auto name = boost::lexical_cast<std::string>(extractFormParamsFromBody("name", extractBodyContent(session)));
    auto status = boost::lexical_cast<std::string>(extractFormParamsFromBody("status", extractBodyContent(session)));
    // Getting the path params
    int64_t petId = request->get_path_parameter("petId", 0L);
    
    int status_code = 500;
    std::string result = "";
    
    try {
        status_code =
            handler_POST(petId, name, status);
    }
    catch(const PetApiException& e) {
        std::tie(status_code, result) = handlePetApiException(e);
    }
    catch(const std::exception& e) {
        std::tie(status_code, result) = handleStdException(e);
    }
    catch(...) {
        std::tie(status_code, result) = handleUnspecifiedException();
    }
    
    std::multimap< std::string, std::string > responseHeaders {};
    static const std::vector<std::string> contentTypes{
        "application/json"
    };
    static const std::string acceptTypes{
        "application/x-www-form-urlencoded, "
    };
    
    if (status_code == 200) {
        responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
        if (!acceptTypes.empty()) {
            responseHeaders.insert(std::make_pair("Accept", acceptTypes));
        }
    
        returnResponse(session, 200, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 405) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Invalid input";
    
        returnResponse(session, 405, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    defaultSessionClose(session, status_code, result);
}

int PetPetIdResource::handler_DELETE(
        int64_t & petId, std::string & apiKey)
{
    return handler_DELETE_func(petId, apiKey);
}

std::pair<int, Pet> PetPetIdResource::handler_GET(
    int64_t & petId)
{
    return handler_GET_func(petId);
}
int PetPetIdResource::handler_POST(
    int64_t & petId, std::string & name, std::string & status)
{
    return handler_POST_func(petId, name, status);
}

std::string PetPetIdResource::extractBodyContent(const std::shared_ptr<restbed::Session>& session) {
  const auto request = session->get_request();
  int content_length = request->get_header("Content-Length", 0);
  std::string bodyContent;
  session->fetch(content_length,
                 [&bodyContent](const std::shared_ptr<restbed::Session> session,
                                const restbed::Bytes &body) {
                   bodyContent = restbed::String::format(
                       "%.*s\n", (int)body.size(), body.data());
                 });
  return bodyContent;
}

std::string PetPetIdResource::extractFormParamsFromBody(const std::string& paramName, const std::string& body) {
    const auto uri = restbed::Uri("urlencoded?" + body, true);
    const auto params = uri.get_query_parameters();
    const auto result = params.find(paramName);
    if (result != params.cend()) {
        return result->second;
    }
    return "";
}
PetFindByStatusResource::PetFindByStatusResource(const std::string& context /* = "/v2" */)
{
	this->set_path(context + "/pet/findByStatus");
	this->set_method_handler("GET",
		std::bind(&PetFindByStatusResource::handler_GET_internal, this,
			std::placeholders::_1));
}

std::pair<int, std::string> PetFindByStatusResource::handlePetApiException(const PetApiException& e)
{
    return std::make_pair<int, std::string>(e.getStatus(), e.what());
}

std::pair<int, std::string> PetFindByStatusResource::handleStdException(const std::exception& e)
{
    return std::make_pair<int, std::string>(500, e.what());
}

std::pair<int, std::string> PetFindByStatusResource::handleUnspecifiedException()
{
    return std::make_pair<int, std::string>(500, "Unknown exception occurred");
}

void PetFindByStatusResource::setResponseHeader(const std::shared_ptr<restbed::Session>& session, const std::string& header)
{
    session->set_header(header, "");
}

void PetFindByStatusResource::returnResponse(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result, std::multimap<std::string, std::string>& responseHeaders)
{
    responseHeaders.insert(std::make_pair("Connection", "close"));
    session->close(status, result, responseHeaders);
}

void PetFindByStatusResource::defaultSessionClose(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result)
{
    session->close(status, result, { {"Connection", "close"} });
}

void PetFindByStatusResource::handler_GET_internal(const std::shared_ptr<restbed::Session> session)
{
    const auto request = session->get_request();
    // Getting the query params
    std::string status_raw = request->get_query_parameter("status");
    std::vector<std::string> status;
    std::vector<std::string> status_temp;
    boost::split(status_temp, status_raw, boost::is_any_of(","));
    std::copy(status_temp.begin(), status_temp.end(), std::inserter(status, std::next(status.begin())));
    
    int status_code = 500;
    std::vector<Pet> resultObject = std::vector<Pet>();
    std::string result = "";
    
    try {
        std::tie(status_code, resultObject) =
            handler_GET(status);
    }
    catch(const PetApiException& e) {
        std::tie(status_code, result) = handlePetApiException(e);
    }
    catch(const std::exception& e) {
        std::tie(status_code, result) = handleStdException(e);
    }
    catch(...) {
        std::tie(status_code, result) = handleUnspecifiedException();
    }
    
    std::multimap< std::string, std::string > responseHeaders {};
    static const std::vector<std::string> contentTypes{
        "application/xml","application/json",
    };
    static const std::string acceptTypes{
    };
    
    if (status_code == 200) {
        responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
        if (!acceptTypes.empty()) {
            responseHeaders.insert(std::make_pair("Accept", acceptTypes));
        }
    
        returnResponse(session, 200, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 400) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Invalid status value";
    
        returnResponse(session, 400, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    defaultSessionClose(session, status_code, result);
}


std::pair<int, std::vector<Pet>> PetFindByStatusResource::handler_GET(
        std::vector<std::string> & status)
{
    return handler_GET_func(status);
}


std::string PetFindByStatusResource::extractBodyContent(const std::shared_ptr<restbed::Session>& session) {
  const auto request = session->get_request();
  int content_length = request->get_header("Content-Length", 0);
  std::string bodyContent;
  session->fetch(content_length,
                 [&bodyContent](const std::shared_ptr<restbed::Session> session,
                                const restbed::Bytes &body) {
                   bodyContent = restbed::String::format(
                       "%.*s\n", (int)body.size(), body.data());
                 });
  return bodyContent;
}

std::string PetFindByStatusResource::extractFormParamsFromBody(const std::string& paramName, const std::string& body) {
    const auto uri = restbed::Uri("urlencoded?" + body, true);
    const auto params = uri.get_query_parameters();
    const auto result = params.find(paramName);
    if (result != params.cend()) {
        return result->second;
    }
    return "";
}
PetFindByTagsResource::PetFindByTagsResource(const std::string& context /* = "/v2" */)
{
	this->set_path(context + "/pet/findByTags");
	this->set_method_handler("GET",
		std::bind(&PetFindByTagsResource::handler_GET_internal, this,
			std::placeholders::_1));
}

std::pair<int, std::string> PetFindByTagsResource::handlePetApiException(const PetApiException& e)
{
    return std::make_pair<int, std::string>(e.getStatus(), e.what());
}

std::pair<int, std::string> PetFindByTagsResource::handleStdException(const std::exception& e)
{
    return std::make_pair<int, std::string>(500, e.what());
}

std::pair<int, std::string> PetFindByTagsResource::handleUnspecifiedException()
{
    return std::make_pair<int, std::string>(500, "Unknown exception occurred");
}

void PetFindByTagsResource::setResponseHeader(const std::shared_ptr<restbed::Session>& session, const std::string& header)
{
    session->set_header(header, "");
}

void PetFindByTagsResource::returnResponse(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result, std::multimap<std::string, std::string>& responseHeaders)
{
    responseHeaders.insert(std::make_pair("Connection", "close"));
    session->close(status, result, responseHeaders);
}

void PetFindByTagsResource::defaultSessionClose(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result)
{
    session->close(status, result, { {"Connection", "close"} });
}

void PetFindByTagsResource::handler_GET_internal(const std::shared_ptr<restbed::Session> session)
{
    const auto request = session->get_request();
    // Getting the query params
    std::string tags_raw = request->get_query_parameter("tags");
    std::set<std::string> tags;
    std::vector<std::string> tags_temp;
    boost::split(tags_temp, tags_raw, boost::is_any_of(","));
    std::copy(tags_temp.begin(), tags_temp.end(), std::inserter(tags, std::next(tags.begin())));
    
    int status_code = 500;
    std::set<Pet> resultObject = std::set<Pet>();
    std::string result = "";
    
    try {
        std::tie(status_code, resultObject) =
            handler_GET(tags);
    }
    catch(const PetApiException& e) {
        std::tie(status_code, result) = handlePetApiException(e);
    }
    catch(const std::exception& e) {
        std::tie(status_code, result) = handleStdException(e);
    }
    catch(...) {
        std::tie(status_code, result) = handleUnspecifiedException();
    }
    
    std::multimap< std::string, std::string > responseHeaders {};
    static const std::vector<std::string> contentTypes{
        "application/xml","application/json",
    };
    static const std::string acceptTypes{
    };
    
    if (status_code == 200) {
        responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
        if (!acceptTypes.empty()) {
            responseHeaders.insert(std::make_pair("Accept", acceptTypes));
        }
    
        returnResponse(session, 200, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    if (status_code == 400) {
        responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
        result = "Invalid tag value";
    
        returnResponse(session, 400, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    defaultSessionClose(session, status_code, result);
}


std::pair<int, std::set<Pet>> PetFindByTagsResource::handler_GET(
        std::set<std::string> & tags)
{
    return handler_GET_func(tags);
}


std::string PetFindByTagsResource::extractBodyContent(const std::shared_ptr<restbed::Session>& session) {
  const auto request = session->get_request();
  int content_length = request->get_header("Content-Length", 0);
  std::string bodyContent;
  session->fetch(content_length,
                 [&bodyContent](const std::shared_ptr<restbed::Session> session,
                                const restbed::Bytes &body) {
                   bodyContent = restbed::String::format(
                       "%.*s\n", (int)body.size(), body.data());
                 });
  return bodyContent;
}

std::string PetFindByTagsResource::extractFormParamsFromBody(const std::string& paramName, const std::string& body) {
    const auto uri = restbed::Uri("urlencoded?" + body, true);
    const auto params = uri.get_query_parameters();
    const auto result = params.find(paramName);
    if (result != params.cend()) {
        return result->second;
    }
    return "";
}
PetPetIdUploadImageResource::PetPetIdUploadImageResource(const std::string& context /* = "/v2" */)
{
	this->set_path(context + "/pet/{petId: .*}/uploadImage");
	this->set_method_handler("POST",
		std::bind(&PetPetIdUploadImageResource::handler_POST_internal, this,
			std::placeholders::_1));
}

std::pair<int, std::string> PetPetIdUploadImageResource::handlePetApiException(const PetApiException& e)
{
    return std::make_pair<int, std::string>(e.getStatus(), e.what());
}

std::pair<int, std::string> PetPetIdUploadImageResource::handleStdException(const std::exception& e)
{
    return std::make_pair<int, std::string>(500, e.what());
}

std::pair<int, std::string> PetPetIdUploadImageResource::handleUnspecifiedException()
{
    return std::make_pair<int, std::string>(500, "Unknown exception occurred");
}

void PetPetIdUploadImageResource::setResponseHeader(const std::shared_ptr<restbed::Session>& session, const std::string& header)
{
    session->set_header(header, "");
}

void PetPetIdUploadImageResource::returnResponse(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result, std::multimap<std::string, std::string>& responseHeaders)
{
    responseHeaders.insert(std::make_pair("Connection", "close"));
    session->close(status, result, responseHeaders);
}

void PetPetIdUploadImageResource::defaultSessionClose(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result)
{
    session->close(status, result, { {"Connection", "close"} });
}

void PetPetIdUploadImageResource::handler_POST_internal(const std::shared_ptr<restbed::Session> session)
{
    const auto request = session->get_request();
    auto additionalMetadata = boost::lexical_cast<std::string>(extractFormParamsFromBody("additionalMetadata", extractBodyContent(session)));
    auto file = boost::lexical_cast<std::string>(extractFormParamsFromBody("file", extractBodyContent(session)));
    // Getting the path params
    int64_t petId = request->get_path_parameter("petId", 0L);
    
    int status_code = 500;
    ApiResponse resultObject = ApiResponse{};
    std::string result = "";
    
    try {
        std::tie(status_code, resultObject) =
            handler_POST(petId, additionalMetadata, file);
    }
    catch(const PetApiException& e) {
        std::tie(status_code, result) = handlePetApiException(e);
    }
    catch(const std::exception& e) {
        std::tie(status_code, result) = handleStdException(e);
    }
    catch(...) {
        std::tie(status_code, result) = handleUnspecifiedException();
    }
    
    std::multimap< std::string, std::string > responseHeaders {};
    static const std::vector<std::string> contentTypes{
        "application/json",
    };
    static const std::string acceptTypes{
        "multipart/form-data, "
    };
    
    if (status_code == 200) {
        responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
        if (!acceptTypes.empty()) {
            responseHeaders.insert(std::make_pair("Accept", acceptTypes));
        }
    
        result = resultObject.toJsonString();
        returnResponse(session, 200, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    defaultSessionClose(session, status_code, result);
}


std::pair<int, ApiResponse> PetPetIdUploadImageResource::handler_POST(
        int64_t & petId, std::string & additionalMetadata, std::string & file)
{
    return handler_POST_func(petId, additionalMetadata, file);
}


std::string PetPetIdUploadImageResource::extractBodyContent(const std::shared_ptr<restbed::Session>& session) {
  const auto request = session->get_request();
  int content_length = request->get_header("Content-Length", 0);
  std::string bodyContent;
  session->fetch(content_length,
                 [&bodyContent](const std::shared_ptr<restbed::Session> session,
                                const restbed::Bytes &body) {
                   bodyContent = restbed::String::format(
                       "%.*s\n", (int)body.size(), body.data());
                 });
  return bodyContent;
}

std::string PetPetIdUploadImageResource::extractFormParamsFromBody(const std::string& paramName, const std::string& body) {
    const auto uri = restbed::Uri("urlencoded?" + body, true);
    const auto params = uri.get_query_parameters();
    const auto result = params.find(paramName);
    if (result != params.cend()) {
        return result->second;
    }
    return "";
}
FakePetIdUploadImageWithRequiredFileResource::FakePetIdUploadImageWithRequiredFileResource(const std::string& context /* = "/v2" */)
{
	this->set_path(context + "/fake/{petId: .*}/uploadImageWithRequiredFile");
	this->set_method_handler("POST",
		std::bind(&FakePetIdUploadImageWithRequiredFileResource::handler_POST_internal, this,
			std::placeholders::_1));
}

std::pair<int, std::string> FakePetIdUploadImageWithRequiredFileResource::handlePetApiException(const PetApiException& e)
{
    return std::make_pair<int, std::string>(e.getStatus(), e.what());
}

std::pair<int, std::string> FakePetIdUploadImageWithRequiredFileResource::handleStdException(const std::exception& e)
{
    return std::make_pair<int, std::string>(500, e.what());
}

std::pair<int, std::string> FakePetIdUploadImageWithRequiredFileResource::handleUnspecifiedException()
{
    return std::make_pair<int, std::string>(500, "Unknown exception occurred");
}

void FakePetIdUploadImageWithRequiredFileResource::setResponseHeader(const std::shared_ptr<restbed::Session>& session, const std::string& header)
{
    session->set_header(header, "");
}

void FakePetIdUploadImageWithRequiredFileResource::returnResponse(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result, std::multimap<std::string, std::string>& responseHeaders)
{
    responseHeaders.insert(std::make_pair("Connection", "close"));
    session->close(status, result, responseHeaders);
}

void FakePetIdUploadImageWithRequiredFileResource::defaultSessionClose(const std::shared_ptr<restbed::Session>& session, const int status, const std::string& result)
{
    session->close(status, result, { {"Connection", "close"} });
}

void FakePetIdUploadImageWithRequiredFileResource::handler_POST_internal(const std::shared_ptr<restbed::Session> session)
{
    const auto request = session->get_request();
    auto additionalMetadata = boost::lexical_cast<std::string>(extractFormParamsFromBody("additionalMetadata", extractBodyContent(session)));
    auto requiredFile = boost::lexical_cast<std::string>(extractFormParamsFromBody("requiredFile", extractBodyContent(session)));
    // Getting the path params
    int64_t petId = request->get_path_parameter("petId", 0L);
    
    int status_code = 500;
    ApiResponse resultObject = ApiResponse{};
    std::string result = "";
    
    try {
        std::tie(status_code, resultObject) =
            handler_POST(petId, requiredFile, additionalMetadata);
    }
    catch(const PetApiException& e) {
        std::tie(status_code, result) = handlePetApiException(e);
    }
    catch(const std::exception& e) {
        std::tie(status_code, result) = handleStdException(e);
    }
    catch(...) {
        std::tie(status_code, result) = handleUnspecifiedException();
    }
    
    std::multimap< std::string, std::string > responseHeaders {};
    static const std::vector<std::string> contentTypes{
        "application/json",
    };
    static const std::string acceptTypes{
        "multipart/form-data, "
    };
    
    if (status_code == 200) {
        responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
        if (!acceptTypes.empty()) {
            responseHeaders.insert(std::make_pair("Accept", acceptTypes));
        }
    
        result = resultObject.toJsonString();
        returnResponse(session, 200, result.empty() ? "{}" : result, responseHeaders);
        return;
    }
    defaultSessionClose(session, status_code, result);
}


std::pair<int, ApiResponse> FakePetIdUploadImageWithRequiredFileResource::handler_POST(
        int64_t & petId, std::string & requiredFile, std::string & additionalMetadata)
{
    return handler_POST_func(petId, requiredFile, additionalMetadata);
}


std::string FakePetIdUploadImageWithRequiredFileResource::extractBodyContent(const std::shared_ptr<restbed::Session>& session) {
  const auto request = session->get_request();
  int content_length = request->get_header("Content-Length", 0);
  std::string bodyContent;
  session->fetch(content_length,
                 [&bodyContent](const std::shared_ptr<restbed::Session> session,
                                const restbed::Bytes &body) {
                   bodyContent = restbed::String::format(
                       "%.*s\n", (int)body.size(), body.data());
                 });
  return bodyContent;
}

std::string FakePetIdUploadImageWithRequiredFileResource::extractFormParamsFromBody(const std::string& paramName, const std::string& body) {
    const auto uri = restbed::Uri("urlencoded?" + body, true);
    const auto params = uri.get_query_parameters();
    const auto result = params.find(paramName);
    if (result != params.cend()) {
        return result->second;
    }
    return "";
}

} /* namespace PetApiResources */

PetApi::PetApi(std::shared_ptr<restbed::Service> const& restbedService)
: m_service(restbedService)
{
}

PetApi::~PetApi() {}

std::shared_ptr<PetApiResources::PetResource> PetApi::getPetResource() {
    if (!m_spPetResource) {
        setResource(std::make_shared<PetApiResources::PetResource>());
    }
    return m_spPetResource;
}
std::shared_ptr<PetApiResources::PetPetIdResource> PetApi::getPetPetIdResource() {
    if (!m_spPetPetIdResource) {
        setResource(std::make_shared<PetApiResources::PetPetIdResource>());
    }
    return m_spPetPetIdResource;
}
std::shared_ptr<PetApiResources::PetFindByStatusResource> PetApi::getPetFindByStatusResource() {
    if (!m_spPetFindByStatusResource) {
        setResource(std::make_shared<PetApiResources::PetFindByStatusResource>());
    }
    return m_spPetFindByStatusResource;
}
std::shared_ptr<PetApiResources::PetFindByTagsResource> PetApi::getPetFindByTagsResource() {
    if (!m_spPetFindByTagsResource) {
        setResource(std::make_shared<PetApiResources::PetFindByTagsResource>());
    }
    return m_spPetFindByTagsResource;
}
std::shared_ptr<PetApiResources::PetPetIdUploadImageResource> PetApi::getPetPetIdUploadImageResource() {
    if (!m_spPetPetIdUploadImageResource) {
        setResource(std::make_shared<PetApiResources::PetPetIdUploadImageResource>());
    }
    return m_spPetPetIdUploadImageResource;
}
std::shared_ptr<PetApiResources::FakePetIdUploadImageWithRequiredFileResource> PetApi::getFakePetIdUploadImageWithRequiredFileResource() {
    if (!m_spFakePetIdUploadImageWithRequiredFileResource) {
        setResource(std::make_shared<PetApiResources::FakePetIdUploadImageWithRequiredFileResource>());
    }
    return m_spFakePetIdUploadImageWithRequiredFileResource;
}
void PetApi::setResource(std::shared_ptr<PetApiResources::PetResource> resource) {
    m_spPetResource = resource;
    m_service->publish(m_spPetResource);
}
void PetApi::setResource(std::shared_ptr<PetApiResources::PetPetIdResource> resource) {
    m_spPetPetIdResource = resource;
    m_service->publish(m_spPetPetIdResource);
}
void PetApi::setResource(std::shared_ptr<PetApiResources::PetFindByStatusResource> resource) {
    m_spPetFindByStatusResource = resource;
    m_service->publish(m_spPetFindByStatusResource);
}
void PetApi::setResource(std::shared_ptr<PetApiResources::PetFindByTagsResource> resource) {
    m_spPetFindByTagsResource = resource;
    m_service->publish(m_spPetFindByTagsResource);
}
void PetApi::setResource(std::shared_ptr<PetApiResources::PetPetIdUploadImageResource> resource) {
    m_spPetPetIdUploadImageResource = resource;
    m_service->publish(m_spPetPetIdUploadImageResource);
}
void PetApi::setResource(std::shared_ptr<PetApiResources::FakePetIdUploadImageWithRequiredFileResource> resource) {
    m_spFakePetIdUploadImageWithRequiredFileResource = resource;
    m_service->publish(m_spFakePetIdUploadImageWithRequiredFileResource);
}
void PetApi::setPetApiPetResource(std::shared_ptr<PetApiResources::PetResource> spPetResource) {
    m_spPetResource = spPetResource;
    m_service->publish(m_spPetResource);
}
void PetApi::setPetApiPetPetIdResource(std::shared_ptr<PetApiResources::PetPetIdResource> spPetPetIdResource) {
    m_spPetPetIdResource = spPetPetIdResource;
    m_service->publish(m_spPetPetIdResource);
}
void PetApi::setPetApiPetFindByStatusResource(std::shared_ptr<PetApiResources::PetFindByStatusResource> spPetFindByStatusResource) {
    m_spPetFindByStatusResource = spPetFindByStatusResource;
    m_service->publish(m_spPetFindByStatusResource);
}
void PetApi::setPetApiPetFindByTagsResource(std::shared_ptr<PetApiResources::PetFindByTagsResource> spPetFindByTagsResource) {
    m_spPetFindByTagsResource = spPetFindByTagsResource;
    m_service->publish(m_spPetFindByTagsResource);
}
void PetApi::setPetApiPetPetIdUploadImageResource(std::shared_ptr<PetApiResources::PetPetIdUploadImageResource> spPetPetIdUploadImageResource) {
    m_spPetPetIdUploadImageResource = spPetPetIdUploadImageResource;
    m_service->publish(m_spPetPetIdUploadImageResource);
}
void PetApi::setPetApiFakePetIdUploadImageWithRequiredFileResource(std::shared_ptr<PetApiResources::FakePetIdUploadImageWithRequiredFileResource> spFakePetIdUploadImageWithRequiredFileResource) {
    m_spFakePetIdUploadImageWithRequiredFileResource = spFakePetIdUploadImageWithRequiredFileResource;
    m_service->publish(m_spFakePetIdUploadImageWithRequiredFileResource);
}


void PetApi::publishDefaultResources() {
    if (!m_spPetResource) {
        setResource(std::make_shared<PetApiResources::PetResource>());
    }
    if (!m_spPetPetIdResource) {
        setResource(std::make_shared<PetApiResources::PetPetIdResource>());
    }
    if (!m_spPetFindByStatusResource) {
        setResource(std::make_shared<PetApiResources::PetFindByStatusResource>());
    }
    if (!m_spPetFindByTagsResource) {
        setResource(std::make_shared<PetApiResources::PetFindByTagsResource>());
    }
    if (!m_spPetPetIdUploadImageResource) {
        setResource(std::make_shared<PetApiResources::PetPetIdUploadImageResource>());
    }
    if (!m_spFakePetIdUploadImageWithRequiredFileResource) {
        setResource(std::make_shared<PetApiResources::FakePetIdUploadImageWithRequiredFileResource>());
    }
}

std::shared_ptr<restbed::Service> PetApi::service() {
    return m_service;
}


}
}
}
}

