#pragma once
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/common.h>
#include "acl_cpp/http/http_request.hpp"
#include "acl_cpp/http/http_response.hpp"

namespace google {
namespace protobuf {

class MessageLite;

namespace io {

/**
 * ʹ HTTP Э鷢 protobuf ˣͬʱȴӦ
 */
class LIBPROTOBUF_EXPORT http_request
{
public:
	/**
	 * 캯һʹ HTTP ûͷ֮ʱ
	 * ʹñ캯ӶͻһϷͶ
	 * @param request {acl::http_request*} HTTP ͻ󣬷ǿ
	 */
	explicit http_request(acl::http_request* request);

	/**
	 * 캯ڲ HTTP Զͷ֮ʱ
	 * ʹñ캯
	 * @param addr {const char*} http ַʽip:port
	 * @param conn_timeout {int} ӷĳʱʱ䣨룩
	 * @param rw_timeout {int} IO ʱʱ䣨룩
	 */
	explicit http_request(const char* addr, int conn_timeout = 60,
		int rw_timeout = 60);

	~http_request();

	/**
	 * ; protobuf лݰͬʱշӦлݰ
	 * @param in {const MessageLite&} ͻɵݰ
	 * @param out {MessageLite*} 洢Ӧݰ
	 * @return {bool} Ƿɹ
	 */
	bool rpc_request(const MessageLite& in, MessageLite* out);

	double request_spent() const
	{
		return request_spent_;
	}

	double response_spent() const
	{
		return response_spent_;
	}

	double build_spent() const
	{
		return build_spent_;
	}

	double parse_spent() const
	{
		return parse_spent_;
	}
private:
	acl::http_request* request_;
	acl::http_request* request_inner_;
	char* addr_;
	int   conn_timeout_;
	int   rw_timeout_;

	double request_spent_;
	double response_spent_;
	double build_spent_;
	double parse_spent_;
};

/**
 * ʹñտͻͬʱظͻ
 */
class LIBPROTOBUF_EXPORT http_response
{
public:
	/**
	 * 캯
	 * @param response {acl::http_response*} ͻķӶ
	 */
	explicit http_response(acl::http_response* response);

	~http_response();

	/**
	 * ˵ñ̶ȡͻ˵
	 * @param out {MessageLite*} 洢ͻ
	 * @return {bool} Ƿɹ
	 */
	bool read_request(MessageLite* out);

	/**
	 * ̷ͨظͻ
	 * @param int {const MessageLite&} ɵĽ
	 * @return {bool} дǷɹ
	 */
	bool send_response(const MessageLite& in);

	double header_spent() const
	{
		return header_spent_;
	}

	double body_spent() const
	{
		return body_spent_;
	}

	double parse_spent() const
	{
		return parse_spent_;
	}

	double build_spent() const
	{
		return build_spent_;
	}

	double response_spent() const
	{
		return response_spent_;
	}
private:
	acl::http_response* response_;
	double header_spent_;
	double body_spent_;
	double parse_spent_;
	double build_spent_;
	double response_spent_;
};

}  // namespace io
}  // namespace protobuf
}  // namespace google
