//! \~\file pihttptypes.h
//! \~\ingroup HTTP
//! \~\brief
//! \~english Shared HTTP message container types
//! \~russian Общие типы контейнеров HTTP-сообщений
/*
	PIP - Platform Independent Primitives
	Shared HTTP message container types
	Ivan Pelipenko peri4ko@yandex.ru

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef pihttptypes_h
#define pihttptypes_h

#include "pihttpconstants.h"
#include "pip_export.h"
#include "pistringlist.h"


//! \~english Namespace with shared HTTP data types.
//! \~russian Пространство имен с общими HTTP-типами данных.
namespace PIHTTP {


//! \~\ingroup HTTP
//! \~\brief
//! \~english Immutable HTTP message view with accessors for method, path, headers and body.
//! \~russian Неизменяемое HTTP-сообщение с доступом к методу, пути, заголовкам и телу.
class PIP_EXPORT MessageConst {
public:
	//! \~english Returns the HTTP method of the message.
	//! \~russian Возвращает HTTP-метод сообщения.
	PIHTTP::Method method() const { return m_method; }

	//! \~english Returns the HTTP status code of the message.
	//! \~russian Возвращает HTTP-код статуса сообщения.
	PIHTTP::Code code() const { return m_code; }

	//! \~english Returns \c true for informational status codes in the 1xx range.
	//! \~russian Возвращает \c true для информационных кодов статуса из диапазона 1xx.
	bool isCodeInformational() const;

	//! \~english Returns \c true for successful status codes in the 2xx range.
	//! \~russian Возвращает \c true для успешных кодов статуса из диапазона 2xx.
	bool isCodeSuccess() const;

	//! \~english Returns \c true for redirection status codes in the 3xx range.
	//! \~russian Возвращает \c true для кодов перенаправления из диапазона 3xx.
	bool isCodeRedirection() const;

	//! \~english Returns \c true for client error status codes in the 4xx range.
	//! \~russian Возвращает \c true для кодов ошибки клиента из диапазона 4xx.
	bool isCodeClientError() const;

	//! \~english Returns \c true for server error status codes in the 5xx range.
	//! \~russian Возвращает \c true для кодов ошибки сервера из диапазона 5xx.
	bool isCodeServerError() const;

	//! \~english Returns \c true for any client or server error status code.
	//! \~russian Возвращает \c true для любого кода ошибки клиента или сервера.
	bool isCodeError() const { return isCodeClientError() || isCodeServerError(); }


	//! \~english Returns the request path or response target path.
	//! \~russian Возвращает путь запроса или целевой путь ответа.
	const PIString & path() const { return m_path; }

	//! \~english Returns the path split into non-empty components.
	//! \~russian Возвращает путь, разбитый на непустые компоненты.
	PIStringList pathList() const { return m_path.split('/').removeAll({}); }

	//! \~english Returns the message body.
	//! \~russian Возвращает тело сообщения.
	const PIByteArray & body() const { return m_body; }

	//! \~english Returns all message headers.
	//! \~russian Возвращает все заголовки сообщения.
	const PIMap<PIString, PIString> & headers() const { return m_headers; }

	//! \~english Returns parsed query arguments from the URL.
	//! \~russian Возвращает разобранные query-аргументы URL.
	const PIMap<PIString, PIString> & queryArguments() const { return m_query_arguments; }

	//! \~english Returns extracted path arguments.
	//! \~russian Возвращает извлеченные аргументы пути.
	const PIMap<PIString, PIString> & pathArguments() const { return m_path_arguments; }

	//! \~english Returns the combined argument map from query and path arguments.
	//! \~russian Возвращает объединенную карту аргументов из query и path.
	const PIMap<PIString, PIString> & arguments() const { return m_arguments; }

protected:
	PIHTTP::Method m_method = PIHTTP::Method::Unknown;
	PIHTTP::Code m_code     = PIHTTP::Code::Ok;
	PIString m_path;
	PIByteArray m_body;
	PIMap<PIString, PIString> m_headers;
	PIMap<PIString, PIString> m_query_arguments, m_path_arguments, m_arguments;
};


//! \~\ingroup HTTP
//! \~\brief
//! \~english Mutable HTTP message with setters and argument/header modifiers.
//! \~russian Изменяемое HTTP-сообщение с сеттерами и методами изменения аргументов и заголовков.
class PIP_EXPORT MessageMutable: public MessageConst {
public:
	//! \~english Sets the HTTP method.
	//! \~russian Устанавливает HTTP-метод.
	MessageMutable & setMethod(PIHTTP::Method m);

	//! \~english Sets the HTTP status code.
	//! \~russian Устанавливает HTTP-код статуса.
	MessageMutable & setCode(PIHTTP::Code c);

	//! \~english Sets the request path or response target path.
	//! \~russian Устанавливает путь запроса или целевой путь ответа.
	MessageMutable & setPath(PIString p);

	//! \~english Sets the message body.
	//! \~russian Устанавливает тело сообщения.
	MessageMutable & setBody(PIByteArray b);


	//! \~english Returns all message headers.
	//! \~russian Возвращает все заголовки сообщения.
	const PIMap<PIString, PIString> & headers() const { return m_headers; }

	//! \~english Returns a modifiable map of all arguments.
	//! \~russian Возвращает изменяемую карту всех аргументов.
	PIMap<PIString, PIString> & arguments() { return m_arguments; }

	//! \~english Returns all arguments.
	//! \~russian Возвращает все аргументы.
	const PIMap<PIString, PIString> & arguments() const { return m_arguments; }

	//! \~english Returns query arguments.
	//! \~russian Возвращает query-аргументы.
	const PIMap<PIString, PIString> & queryArguments() const { return m_query_arguments; }

	//! \~english Returns path arguments.
	//! \~russian Возвращает аргументы пути.
	const PIMap<PIString, PIString> & pathArguments() const { return m_path_arguments; }


	//! \~english Returns a modifiable map of all message headers.
	//! \~russian Возвращает изменяемую карту всех заголовков сообщения.
	PIMap<PIString, PIString> & headers() { return m_headers; }

	//! \~english Adds or replaces a header in the message.
	//! \~russian Добавляет заголовок в сообщение или заменяет существующий.
	MessageMutable & addHeader(const PIString & header, const PIString & value);

	//! \~english Removes a header from the message.
	//! \~russian Удаляет заголовок из сообщения.
	MessageMutable & removeHeader(const PIString & header);


	//! \~english Returns a modifiable map of query arguments.
	//! \~russian Возвращает изменяемую карту query-аргументов.
	PIMap<PIString, PIString> & queryArguments() { return m_query_arguments; }

	//! \~english Adds or replaces a query argument.
	//! \~russian Добавляет query-аргумент или заменяет существующий.
	MessageMutable & addQueryArgument(const PIString & arg, const PIString & value);

	//! \~english Removes a query argument.
	//! \~russian Удаляет query-аргумент.
	MessageMutable & removeQueryArgument(const PIString & arg);


	//! \~english Returns a modifiable map of path arguments.
	//! \~russian Возвращает изменяемую карту аргументов пути.
	PIMap<PIString, PIString> & pathArguments() { return m_path_arguments; }

	//! \~english Adds or replaces a path argument.
	//! \~russian Добавляет аргумент пути или заменяет существующий.
	MessageMutable & addPathArgument(const PIString & arg, const PIString & value);

	//! \~english Removes a path argument.
	//! \~russian Удаляет аргумент пути.
	MessageMutable & removePathArgument(const PIString & arg);


	//! \~english Creates a message initialized from an HTTP status code.
	//! \~russian Создает сообщение, инициализированное HTTP-кодом статуса.
	static MessageMutable fromCode(PIHTTP::Code c);

	//! \~english Creates a message initialized from an HTTP method.
	//! \~russian Создает сообщение, инициализированное HTTP-методом.
	static MessageMutable fromMethod(PIHTTP::Method m);
};


//! \~english Returns the canonical string representation of an HTTP method.
//! \~russian Возвращает каноническое строковое представление HTTP-метода.
PIP_EXPORT const char * methodName(Method m);


}; // namespace PIHTTP


#endif
