#include "redfish_passthrough_plugin.h"

#include <memory>
#include <utility>

#include "gmock.h"
#include "gunit.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "redfish_query_engine/http/client.h"
#include "mock_redfish_plugin.h"
#include "request_response.h"
#include "sse/sse_parser.h"
#include "util/task/status_macros.h"

namespace {

using ::testing::A;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Not;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::status::IsOk;

using ProxyRequest = milotic::ProxyRequest;
using ProxyResponse = milotic::ProxyResponse;
using HttpResponse = ecclesia::HttpClient::HttpResponse;
using HttpRequest = ecclesia::HttpClient::HttpRequest;
using ::milotic::ServerSentEvent;

class MockHttpClient : public ecclesia::HttpClient {
 public:
  MOCK_METHOD(absl::StatusOr<HttpResponse>, Get,
              (std::unique_ptr<HttpRequest> request), (override));
  MOCK_METHOD(absl::StatusOr<HttpResponse>, Post,
              (std::unique_ptr<HttpRequest> request), (override));
  MOCK_METHOD(absl::StatusOr<HttpResponse>, Delete,
              (std::unique_ptr<HttpRequest> request), (override));
  MOCK_METHOD(absl::StatusOr<HttpResponse>, Patch,
              (std::unique_ptr<HttpRequest> request), (override));

  MOCK_METHOD(absl::Status, GetIncremental,
              (std::unique_ptr<HttpRequest> request,
               IncrementalResponseHandler* handler),
              (override));
  MOCK_METHOD(absl::Status, PostIncremental,
              (std::unique_ptr<HttpRequest> request,
               IncrementalResponseHandler* handler),
              (override));

  MOCK_METHOD(absl::Status, DeleteIncremental,
              (std::unique_ptr<HttpRequest> request,
               IncrementalResponseHandler* handler),
              (override));
  MOCK_METHOD(absl::Status, PatchIncremental,
              (std::unique_ptr<HttpRequest> request,
               IncrementalResponseHandler* handler),
              (override));
};

class RedfishPassthroughPluginWithMocks
    : public milotic::RedfishPassthroughPluginBase {
 public:
  RedfishPassthroughPluginWithMocks()
      : RedfishPassthroughPluginBase(&mock_http_client,
                                     &subscribe_mock_http_client) {}
  MockHttpClient mock_http_client;
  MockHttpClient subscribe_mock_http_client;
};

TEST(RedfishPassthroughPluginTest, SubscribeWithCorrectContentTypeSucceeds) {
  RedfishPassthroughPluginWithMocks plugin;
  milotic::MockEventHandler mock_event_handler;

  ON_CALL(mock_event_handler, IsCancelled).WillByDefault(Return(false));

  EXPECT_CALL(plugin.subscribe_mock_http_client, GetIncremental)
      .WillOnce(Invoke([](std::unique_ptr<HttpRequest> request,
                          ecclesia::HttpClient::IncrementalResponseHandler*
                              handler) -> absl::Status {
        RETURN_IF_ERROR(handler->OnResponseHeaders(HttpResponse{
            .code = 200, .headers = {{"CoNtEnT-TyPe", "tExT/EvEnT-StReAm"}}}));
        RETURN_IF_ERROR(handler->OnBodyData("event: test\r\n\r\n"));
        return absl::OkStatus();
      }));

  EXPECT_CALL(mock_event_handler, OnResponse)
      .WillOnce(Return(absl::OkStatus()));
  ServerSentEvent event;
  EXPECT_CALL(mock_event_handler, OnEvent(A<const ServerSentEvent&>()))
      .WillOnce(DoAll(SaveArg<0>(&event), Return(absl::OkStatus())));

  auto request = std::make_unique<ProxyRequest>();
  EXPECT_OK(plugin.Subscribe(std::move(request), &mock_event_handler));
  EXPECT_EQ(event, ServerSentEvent{.event = "test"});
}

TEST(RedfishPassthroughPluginTest, SubscribeWithWrongContentTypeFails) {
  RedfishPassthroughPluginWithMocks plugin;
  milotic::MockEventHandler mock_event_handler;

  ON_CALL(mock_event_handler, IsCancelled).WillByDefault(Return(false));

  EXPECT_CALL(plugin.subscribe_mock_http_client, GetIncremental)
      .WillOnce(Invoke([](std::unique_ptr<HttpRequest> request,
                          ecclesia::HttpClient::IncrementalResponseHandler*
                              handler) -> absl::Status {
        RETURN_IF_ERROR(handler->OnResponseHeaders(HttpResponse{
            .code = 200, .headers = {{"CoNtEnT-TyPe", "application/json"}}}));
        RETURN_IF_ERROR(handler->OnBodyData("event: test\r\n\r\n"));
        return absl::OkStatus();
      }));

  EXPECT_CALL(mock_event_handler, OnResponse)
      .WillOnce(Return(absl::OkStatus()));
  EXPECT_CALL(mock_event_handler, OnEvent(A<const ServerSentEvent&>()))
      .Times(0);
  auto request = std::make_unique<ProxyRequest>();
  EXPECT_THAT(plugin.Subscribe(std::move(request), &mock_event_handler),
              Not(IsOk()));
}

TEST(RedfishPassthroughPluginTest, SubscribeWithNoContentTypeFails) {
  RedfishPassthroughPluginWithMocks plugin;
  milotic::MockEventHandler mock_event_handler;

  ON_CALL(mock_event_handler, IsCancelled).WillByDefault(Return(false));

  EXPECT_CALL(plugin.subscribe_mock_http_client, GetIncremental)
      .WillOnce(Invoke([](std::unique_ptr<HttpRequest> request,
                          ecclesia::HttpClient::IncrementalResponseHandler*
                              handler) -> absl::Status {
        RETURN_IF_ERROR(handler->OnResponseHeaders(HttpResponse{.code = 200}));
        RETURN_IF_ERROR(handler->OnBodyData("event: test\r\n\r\n"));
        return absl::OkStatus();
      }));

  EXPECT_CALL(mock_event_handler, OnResponse)
      .WillOnce(Return(absl::OkStatus()));
  EXPECT_CALL(mock_event_handler, OnEvent(A<const ServerSentEvent&>()))
      .Times(0);
  auto request = std::make_unique<ProxyRequest>();
  EXPECT_THAT(plugin.Subscribe(std::move(request), &mock_event_handler),
              Not(IsOk()));
}

}  // namespace
