#pragma once
#include "panda/protocol/websocket/ClientParser.h"
#include "panda/protocol/websocket/ConnectRequest.h"
#include "panda/protocol/websocket/inc.h"
#include "panda/unievent/Loop.h"
#include "panda/unievent/SslContext.h"
#include "panda/unievent/Timer.h"
#include "panda/unievent/forward.h"
#include "panda/unievent/websocket/ServerConnection.h"
#include <panda/log.h>
#include <panda/test/catch.h>
#include <panda/unievent/websocket.h>
#include <panda/unievent/test/AsyncTest.h>
// // #include <memory>
// // #include <functional>
// #include <catch2/generators/catch_generators.hpp>
// #include <catch2/matchers/catch_matchers_string.hpp>
using namespace panda;
// using namespace panda::unievent;
using namespace panda::unievent::test;
using namespace panda::unievent::websocket;
using Location = unievent::http::Server::Location;
using unievent::SslContext;
using unievent::Loop;
using unievent::LoopSP;
using unievent::StreamSP;
using unievent::Pipe;
using unievent::PipeSP;
using unievent::Tcp;
using unievent::TcpSP;
#define VSSL "[v-ssl]"
#define CHECK_PAYLOAD(msg, str) do { \
string full; \
for (auto& s : msg->payload) full += s; \
CHECK(full == str); \
} while (0)
extern bool secure;
struct TServer : Server {
static int dcnt;
using Server::Server;
//string location () const;
//NetLoc netloc () const;
//string uri () const;
static SslContext get_context(string cert_name = "ca");
~TServer () { ++dcnt; }
};
using TServerSP = iptr<TServer>;
struct TClient : Client {
static int dcnt;
net::SockAddr sa;
using Client::Client;
//void request (const RequestSP&);
// ResponseSP get_response (const RequestSP& req);
// ResponseSP get_response (const string& uri, Headers&& = {}, Body&& = {}, bool chunked = false);
// ErrorCode get_error (const RequestSP& req);
// ErrorCode get_error (const string& uri, Headers&& = {}, Body&& = {}, bool chunked = false);
static SslContext get_context(string cert_name, const string& ca_name = "ca");
~TClient () { ++dcnt; }
// friend struct TPool;
};
using TClientSP = iptr<TClient>;
struct ServerPair {
using Parser = panda::protocol::websocket::ClientParser;
using Responses = std::deque<string>;
//using RawResponses = std::deque<string>;
TServerSP server;
StreamSP conn;
ServerConnectionSP sconn;
//RawRequestSP source_request;
ServerPair(const LoopSP&, Server::Config = {}, bool unixsock = false);
void enable_echo();
void autorespond(const string&);
void send (const string& str, Opcode = Opcode::TEXT);
//RawResponseSP get_response ();
//RawResponseSP get_response (const string& s) { conn->write(s); return get_response(); }
//int64_t wait_eof (int tmt = 0);
private:
Parser parser;
bool autores = false;
Responses autoresponse_queue;
//RawResponses response_queue;
//int64_t eof = 0;
};
TServerSP make_server (const LoopSP&, Server::Config = {});
// string active_scheme();
// static auto fail_cb = [](auto...){ FAIL(); };
// int64_t get_time ();
// void time_mark ();
// int64_t time_elapsed ();
// ResponseSP await_response (const RequestSP&, const LoopSP&);
// std::vector<ResponseSP> await_responses(const std::vector<RequestSP>&, const LoopSP&);
// ResponseSP await_any (const std::vector<RequestSP>&, const LoopSP&);
// struct TPool : Pool {
// using Pool::Pool;
// TClientSP request (const RequestSP& req);
// protected:
// ClientSP new_client () override { return new TClient(this); }
// };
// using TPoolSP = iptr<TPool>;
// struct TProxy {
// TcpSP server;
// URISP url;
// };
// TProxy new_proxy(const LoopSP&, const net::SockAddr& sa = net::SockAddr::Inet4("127.0.0.1", 0));
// struct ClientPair {
// TServerSP server;
// TClientSP client;
// TProxy proxy;
// ClientPair (const LoopSP&, bool with_proxy = false);
// };
// TServerSP make_ssl_server (const LoopSP&);