/**
* Digital Voice Modem - Host Software
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / Host Software
*
*/
//
// Based on code from the CRUD project. (https://github.com/venediktov/CRUD)
// Licensed under the BPL-1.0 License (https://opensource.org/license/bsl1-0-html)
//
/*
*   Copyright (c) 2003-2013 Christopher M. Kohlhoff
*   Copyright (C) 2023 by Bryan Biedenkapp N2PLL
*
*   Permission is hereby granted, free of charge, to any person or organization
*   obtaining a copy of the software and accompanying documentation covered by
*   this license (the “Software”) to use, reproduce, display, distribute, execute,
*   and transmit the Software, and to prepare derivative works of the Software, and
*   to permit third-parties to whom the Software is furnished to do so, all subject
*   to the following:
*
*   The copyright notices in the Software and this entire statement, including the
*   above license grant, this restriction and the following disclaimer, must be included
*   in all copies of the Software, in whole or in part, and all derivative works of the
*   Software, unless such copies or derivative works are solely in the form of
*   machine-executable object code generated by a source language processor.
*
*   THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
*   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
*   PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE
*   DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN
*   CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
*   OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined(__REST_HTTP__HTTP_REPLY_H__)
#define __REST_HTTP__HTTP_REPLY_H__

#include "Defines.h"
#include "network/json/json.h"
#include "network/rest/http/HTTPHeaders.h"

#include <string>
#include <vector>

#include <asio.hpp>

namespace network
{
    namespace rest
    {
        namespace http
        {

            // ---------------------------------------------------------------------------
            //  Constants
            // ---------------------------------------------------------------------------

            #define HTTP_GET "GET"
            #define HTTP_POST "POST"
            #define HTTP_PUT "PUT"
            #define HTTP_DELETE "DELETE"
            #define HTTP_OPTIONS "OPTIONS"

            // ---------------------------------------------------------------------------
            //  Structure Declaration
            //      This struct implements a model of a payload to be sent to a
            //      HTTP client/server.
            // ---------------------------------------------------------------------------

            struct HTTPPayload {
                /// <summary>
                /// HTTP Status/Response Codes
                /// </summary>
                enum StatusType {
                    OK = 200,
                    CREATED = 201,
                    ACCEPTED = 202,
                    NO_CONTENT = 204,
                    MULTIPLE_CHOICES = 300,
                    MOVED_PERMANENTLY = 301,
                    MOVED_TEMPORARILY = 302,
                    NOT_MODIFIED = 304,
                    BAD_REQUEST = 400,
                    UNAUTHORIZED = 401,
                    FORBIDDEN = 403,
                    NOT_FOUND = 404,
                    INTERNAL_SERVER_ERROR = 500,
                    NOT_IMPLEMENTED = 501,
                    BAD_GATEWAY = 502,
                    SERVICE_UNAVAILABLE = 503
                } status;

                HTTPHeaders headers;
                std::string content;

                std::string method;
                std::string uri;

                int httpVersionMajor;
                int httpVersionMinor;

                bool isClientPayload = false;

                /// <summary>Convert the payload into a vector of buffers. The buffers do not own the
                /// underlying memory blocks, therefore the payload object must remain valid and
                /// not be changed until the write operation has completed.</summary>
                std::vector<asio::const_buffer> toBuffers();

                /// <summary>Prepares payload for transmission by finalizing status and content type.</summary>
                void payload(json::object& obj, StatusType status = OK);
                /// <summary>Prepares payload for transmission by finalizing status and content type.</summary>
                void payload(std::string& content, StatusType status = OK, const std::string& contentType = "text/html");

                /// <summary>Get a request payload.</summary>
                static HTTPPayload requestPayload(std::string method, std::string uri);
                /// <summary>Get a status payload.</summary>
                static HTTPPayload statusPayload(StatusType status, const std::string& contentType = "text/html");

                /// <summary></summary>
                void attachHostHeader(const asio::ip::tcp::endpoint remoteEndpoint);
            private:
                /// <summary></summary>
                void ensureDefaultHeaders(const std::string& contentType = "text/html");
            };
        } // namespace http
    } // namespace rest
} // namespace network

#endif // __REST_HTTP__HTTP_REPLY_H__
