#ifndef PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_BMC_MOCK_SERVER_H_
#define PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_BMC_MOCK_SERVER_H_

#include <chrono>  //  NOLINT(build/c++11)
#include <cstdint>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <memory>
#include <string>
#include <utility>

// NOLINTBEGIN(readability/boost)
#include "absl/strings/string_view.h"
#include "boost/asio/io_context.hpp"
#include "boost/beast/core.hpp"
#include "boost/beast/http.hpp"
#include "boost/beast/version.hpp"
// NOLINTEND(readability/boost)

namespace safepower_agent {
namespace mock_server_test {

// boost ref server
// https://www.boost.org/doc/libs/1_85_0/libs/beast/example/http/server/small/http_server_small.cpp
//
// using a boost http server to test the http client used in gpowerd

namespace beast = boost::beast;    // from <boost/beast.hpp>
namespace http = beast::http;      // from <boost/beast/http.hpp>
namespace net = boost::asio;       // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp;  // from <boost/asio/ip/tcp.hpp>

constexpr absl::string_view goodJson = R"(
{
   "@Message.ExtendedInfo": [
     {
       "@odata.type": "#Message.v1_1_1.Message",
       "Message": "The request completed successfully.",
       "MessageArgs": [],
       "MessageId": "Base.1.13.0.Success",
       "MessageSeverity": "OK",
       "Resolution": "None"
     }
  ]
})";

constexpr absl::string_view testingPowerStateJson = R"(
{
  "@odata.id": "/redfish/v1/Systems/system",
  "@odata.type": "#ComputerSystem.v1_16_0.ComputerSystem",
  "Actions": {
    "#ComputerSystem.Reset": {
      "@Redfish.ActionInfo": "/redfish/v1/Systems/system/ResetActionInfo",
      "target": "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"
    }
  },
  "PowerState": "On",
  "PowerState_On": "On",
  "PowerState_Off": "Off",
  "PowerState_Paused": "Paused",
  "PowerState_PoweringOn": "PoweringOn",
  "PowerState_PoweringOff": "PoweringOff",
  "PowerState_UNSPECIFIED_1": "",
  "PowerState_UNSPECIFIED_2": "a"
})";

constexpr absl::string_view malformedJson = R"(
   "@Message.ExtendedInfo":
       "@odata.type": "#Message.v1_1_1.Message",
       "Message": "The request completed successfully.",
       "MessageArgs": ],
       "MessageId": "Base.1.13.0.Success",
       "MessageSeverity": "OK",
       "Resolution": "None"
     }
  ]
})";

constexpr absl::string_view goodSystemGet = R"(
{
    "@odata.id": "/redfish/v1/Chassis",
    "@odata.type": "#ChassisCollection.ChassisCollection",
    "Members": [
        {
            "@odata.id": "/redfish/v1/Chassis/A"
        },
        {
            "@odata.id": "/redfish/v1/Chassis/B"
        },
        {
            "@odata.id": "/redfish/v1/Chassis/D"
        },
        {
            "@odata.id": "/redfish/v1/Chassis/i0"
        },
        {
            "@odata.id": "/redfish/v1/Chassis/i1"
        },
        {
            "@odata.id": "/redfish/v1/Chassis/i2"
        },
        {
            "@odata.id": "/redfish/v1/Chassis/w1"
        },
        {
            "@odata.id": "/redfish/v1/Chassis/w2"
        },
        {
            "@odata.id": "/redfish/v1/Chassis/w3"
        }
    ],
    "Members@odata.count": 9,
    "Name": "Chassis Collection"
})";

class http_connection : public std::enable_shared_from_this<http_connection> {
 public:
  explicit http_connection(tcp::socket socket)
      : socket_(std::move(socket)), skip_write_(false) {
    std::cerr << "Test server connection made" << std::endl;
  }

  // Initiate the asynchronous operations associated with the connection.
  void start() {
    read_request();
    check_deadline();
  }

 private:
  // The socket for the currently connected client.
  tcp::socket socket_;

  // The buffer for performing reads.
  beast::flat_buffer buffer_{8192};

  // The request message.
  http::request<http::dynamic_body> request_;

  // The response message.
  http::response<http::dynamic_body> response_;

  // The timer for putting a deadline on connection processing.
  net::steady_timer deadline_{socket_.get_executor(), std::chrono::seconds(60)};
  // Asynchronously receive a complete request message.

  bool skip_write_;

  void read_request() {
    auto self = shared_from_this();

    http::async_read(
        socket_, buffer_, request_,
        [self](beast::error_code ec, std::size_t bytes_transferred) {
          boost::ignore_unused(bytes_transferred);
          if (!ec) {
            self->process_request();
          }
        });
  }

  void process_request() {
    response_.version(request_.version());
    response_.keep_alive(false);

    switch (request_.method()) {
      case http::verb::post:
        response_.result(http::status::ok);
        response_.set(http::field::server, "Beast");
        response_.set(http::field::content_type, "text/plain");
        create_post_response();
        break;

      case http::verb::get:
        response_.result(http::status::ok);
        response_.set(http::field::server, "Beast");
        create_get_response();
        break;

      default:
        // We return responses indicating an error if
        // we do not recognize the request method.
        response_.result(http::status::bad_request);
        response_.set(http::field::content_type, "text/plain");
        beast::ostream(response_.body())
            << "Invalid request-method '"
            << std::string(request_.method_string()) << "'";
        break;
    }
    if (!skip_write_) {
      write_response();
    }
  }
  // Construct a response message based on the program state.
  void create_post_response() {
    response_.set(http::field::content_type, "text/html");
    if (request_.target() == "/count") {
      beast::ostream(response_.body()) << "count_answer";
    } else if (request_.target() == "/time") {
      beast::ostream(response_.body()) << "time_answer";
    } else if (request_.target() ==
               "/redfish/v1/Systems/system/Actions/Power.Reset") {
      beast::ostream(response_.body()) << goodJson;
    } else if (request_.target() ==
               "/redfish/v1/Systems/system/Actions/Power.Reset_never_write") {
      skip_write_ = true;
    } else if (request_.target() ==
               "/redfish/v1/Systems/system/Actions/Power.Reset_malformed") {
      beast::ostream(response_.body()) << malformedJson;
    } else {
      std::cerr << "request_.target():" << request_.target() << std::endl;
      response_.result(http::status::not_found);
      response_.set(http::field::content_type, "text/plain");
      beast::ostream(response_.body()) << "File not found\r\n";
    }
  }
  void create_get_response() {
    if (request_.target() == "/count") {
      response_.set(http::field::content_type, "text/html");
      beast::ostream(response_.body()) << "count_answer";
    } else if (request_.target() == "/redfish/v1/Systems/system_get") {
      response_.set(http::field::content_type, "text/html");
      beast::ostream(response_.body()) << goodSystemGet;
    } else if (request_.target() ==
               "/redfish/v1/Systems/system/_testingPowerState") {
      beast::ostream(response_.body()) << testingPowerStateJson;
    } else {
      std::cerr << "request_.target():" << request_.target() << std::endl;
      response_.result(http::status::not_found);
      response_.set(http::field::content_type, "text/plain");
      beast::ostream(response_.body()) << "File not found\r\n";
    }
  }

  // Asynchronously transmit the response message.
  void write_response() {
    auto self = shared_from_this();

    response_.content_length(response_.body().size());

    http::async_write(socket_, response_,
                      [self](beast::error_code ec, std::size_t) {
                        self->socket_.shutdown(tcp::socket::shutdown_send, ec);
                        self->deadline_.cancel();
                      });
  }

  // Check whether we have spent enough time on this connection.
  void check_deadline() {
    auto self = shared_from_this();

    deadline_.async_wait([self](beast::error_code ec) {
      if (!ec) {
        // Close socket to cancel any outstanding operation.
        self->socket_.close(ec);
      }
    });
  }
};

inline void http_server(tcp::acceptor& acceptor, tcp::socket& socket) {
  acceptor.async_accept(socket, [&](beast::error_code ec) {
    if (!ec) {
      std::make_shared<http_connection>(std::move(socket))->start();
    } else {
      std::cerr << "http_server error:" << ec.what() << std::endl;
    }
    http_server(acceptor, socket);
  });
}

class TestBoostServer {
 public:
  std::shared_ptr<tcp::acceptor> acceptor_;
  std::shared_ptr<tcp::socket> socket_;

  void Start(boost::asio::io_context& io_ctx) {
    auto const address = net::ip::make_address("0.0.0.0");
    uint16_t const port = 80;
    auto const doc_root = std::make_shared<std::string>("/redfish/v1/");
    boost::asio::ip::tcp::endpoint ep(address, port);

    socket_ = std::make_shared<tcp::socket>(io_ctx);
    acceptor_ = std::make_shared<tcp::acceptor>(io_ctx, ep);

    http_server(*acceptor_, *socket_);
  }
  ~TestBoostServer() {
    acceptor_->cancel();
    socket_->close();
  }
};

}  // namespace mock_server_test
}  // namespace safepower_agent

#endif  // PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_BMC_MOCK_SERVER_H_
