// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "osp/public/message_demuxer.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "osp/msgs/osp_messages.h"
#include "osp/public/testing/message_demuxer_test_support.h"
#include "platform/test/fake_clock.h"
#include "third_party/tinycbor/src/src/cbor.h"

namespace openscreen {
namespace osp {
namespace {

using ::testing::_;
using ::testing::Invoke;

ErrorOr<size_t> ConvertDecodeResult(ssize_t result) {
  if (result < 0) {
    if (result == -CborErrorUnexpectedEOF)
      return Error::Code::kCborIncompleteMessage;
    else
      return Error::Code::kCborParsing;
  } else {
    return result;
  }
}

class MessageDemuxerTest : public ::testing::Test {
 protected:
  void SetUp() override {
    ASSERT_TRUE(
        msgs::EncodePresentationConnectionOpenRequest(request_, &buffer_));
  }

  void ExpectDecodedRequest(
      ssize_t decode_result,
      const msgs::PresentationConnectionOpenRequest& received_request) {
    ASSERT_GT(decode_result, 0);
    EXPECT_EQ(decode_result, static_cast<ssize_t>(buffer_.size() - 2));
    EXPECT_EQ(request_.request_id, received_request.request_id);
    EXPECT_EQ(request_.presentation_id, received_request.presentation_id);
    EXPECT_EQ(request_.url, received_request.url);
  }

  const uint64_t endpoint_id_ = 13;
  const uint64_t connection_id_ = 45;
  FakeClock fake_clock_{Clock::time_point(std::chrono::milliseconds(1298424))};
  msgs::CborEncodeBuffer buffer_;
  msgs::PresentationConnectionOpenRequest request_{1, "fry-am-the-egg-man",
                                                   "url"};
  MockMessageCallback mock_callback_;
  MessageDemuxer demuxer_{FakeClock::now, MessageDemuxer::kDefaultBufferLimit};
};

}  // namespace

TEST_F(MessageDemuxerTest, WatchStartStop) {
  MessageDemuxer::MessageWatch watch = demuxer_.WatchMessageType(
      endpoint_id_, msgs::Type::kPresentationConnectionOpenRequest,
      &mock_callback_);
  ASSERT_TRUE(watch);

  EXPECT_CALL(mock_callback_, OnStreamMessage(_, _, _, _, _, _)).Times(0);
  demuxer_.OnStreamData(endpoint_id_ + 1, 14, buffer_.data(), buffer_.size());

  msgs::PresentationConnectionOpenRequest received_request;
  ssize_t decode_result = 0;
  EXPECT_CALL(
      mock_callback_,
      OnStreamMessage(endpoint_id_, connection_id_,
                      msgs::Type::kPresentationConnectionOpenRequest, _, _, _))
      .WillOnce(Invoke([&decode_result, &received_request](
                           uint64_t endpoint_id, uint64_t connection_id,
                           msgs::Type message_type, const uint8_t* buffer,
                           size_t buffer_size, Clock::time_point now) {
        decode_result = msgs::DecodePresentationConnectionOpenRequest(
            buffer, buffer_size, &received_request);
        return ConvertDecodeResult(decode_result);
      }));
  demuxer_.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                        buffer_.size());
  ExpectDecodedRequest(decode_result, received_request);

  watch = MessageDemuxer::MessageWatch();
  EXPECT_CALL(mock_callback_, OnStreamMessage(_, _, _, _, _, _)).Times(0);
  demuxer_.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                        buffer_.size());
}

TEST_F(MessageDemuxerTest, BufferPartialMessage) {
  MockMessageCallback mock_callback_;
  constexpr uint64_t endpoint_id_ = 13;

  MessageDemuxer::MessageWatch watch = demuxer_.WatchMessageType(
      endpoint_id_, msgs::Type::kPresentationConnectionOpenRequest,
      &mock_callback_);
  ASSERT_TRUE(watch);

  msgs::PresentationConnectionOpenRequest received_request;
  ssize_t decode_result = 0;
  EXPECT_CALL(
      mock_callback_,
      OnStreamMessage(endpoint_id_, connection_id_,
                      msgs::Type::kPresentationConnectionOpenRequest, _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke([&decode_result, &received_request](
                                 uint64_t endpoint_id, uint64_t connection_id,
                                 msgs::Type message_type, const uint8_t* buffer,
                                 size_t buffer_size, Clock::time_point now) {
        decode_result = msgs::DecodePresentationConnectionOpenRequest(
            buffer, buffer_size, &received_request);
        return ConvertDecodeResult(decode_result);
      }));
  demuxer_.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                        buffer_.size() - 3);
  demuxer_.OnStreamData(endpoint_id_, connection_id_,
                        buffer_.data() + buffer_.size() - 3, 3);
  ExpectDecodedRequest(decode_result, received_request);
}

TEST_F(MessageDemuxerTest, DefaultWatch) {
  MockMessageCallback mock_callback_;
  constexpr uint64_t endpoint_id_ = 13;

  MessageDemuxer::MessageWatch watch = demuxer_.SetDefaultMessageTypeWatch(
      msgs::Type::kPresentationConnectionOpenRequest, &mock_callback_);
  ASSERT_TRUE(watch);

  msgs::PresentationConnectionOpenRequest received_request;
  ssize_t decode_result = 0;
  EXPECT_CALL(
      mock_callback_,
      OnStreamMessage(endpoint_id_, connection_id_,
                      msgs::Type::kPresentationConnectionOpenRequest, _, _, _))
      .WillOnce(Invoke([&decode_result, &received_request](
                           uint64_t endpoint_id, uint64_t connection_id,
                           msgs::Type message_type, const uint8_t* buffer,
                           size_t buffer_size, Clock::time_point now) {
        decode_result = msgs::DecodePresentationConnectionOpenRequest(
            buffer, buffer_size, &received_request);
        return ConvertDecodeResult(decode_result);
      }));
  demuxer_.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                        buffer_.size());
  ExpectDecodedRequest(decode_result, received_request);
}

TEST_F(MessageDemuxerTest, DefaultWatchOverridden) {
  MockMessageCallback mock_callback_global;
  MockMessageCallback mock_callback_;
  constexpr uint64_t endpoint_id_ = 13;

  MessageDemuxer::MessageWatch default_watch =
      demuxer_.SetDefaultMessageTypeWatch(
          msgs::Type::kPresentationConnectionOpenRequest,
          &mock_callback_global);
  ASSERT_TRUE(default_watch);
  MessageDemuxer::MessageWatch watch = demuxer_.WatchMessageType(
      endpoint_id_, msgs::Type::kPresentationConnectionOpenRequest,
      &mock_callback_);
  ASSERT_TRUE(watch);

  msgs::PresentationConnectionOpenRequest received_request;
  ssize_t decode_result = 0;
  EXPECT_CALL(mock_callback_, OnStreamMessage(_, _, _, _, _, _)).Times(0);
  EXPECT_CALL(
      mock_callback_global,
      OnStreamMessage(endpoint_id_ + 1, 14,
                      msgs::Type::kPresentationConnectionOpenRequest, _, _, _))
      .WillOnce(Invoke([&decode_result, &received_request](
                           uint64_t endpoint_id, uint64_t connection_id,
                           msgs::Type message_type, const uint8_t* buffer,
                           size_t buffer_size, Clock::time_point now) {
        decode_result = msgs::DecodePresentationConnectionOpenRequest(
            buffer, buffer_size, &received_request);
        return ConvertDecodeResult(decode_result);
      }));
  demuxer_.OnStreamData(endpoint_id_ + 1, 14, buffer_.data(), buffer_.size());
  ExpectDecodedRequest(decode_result, received_request);

  decode_result = 0;
  EXPECT_CALL(
      mock_callback_,
      OnStreamMessage(endpoint_id_, connection_id_,
                      msgs::Type::kPresentationConnectionOpenRequest, _, _, _))
      .WillOnce(Invoke([&decode_result, &received_request](
                           uint64_t endpoint_id, uint64_t connection_id,
                           msgs::Type message_type, const uint8_t* buffer,
                           size_t buffer_size, Clock::time_point now) {
        decode_result = msgs::DecodePresentationConnectionOpenRequest(
            buffer, buffer_size, &received_request);
        return ConvertDecodeResult(decode_result);
      }));
  demuxer_.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                        buffer_.size());
  ExpectDecodedRequest(decode_result, received_request);
}

TEST_F(MessageDemuxerTest, WatchAfterData) {
  msgs::PresentationConnectionOpenRequest received_request;
  ssize_t decode_result = 0;
  EXPECT_CALL(
      mock_callback_,
      OnStreamMessage(endpoint_id_, connection_id_,
                      msgs::Type::kPresentationConnectionOpenRequest, _, _, _))
      .WillOnce(Invoke([&decode_result, &received_request](
                           uint64_t endpoint_id, uint64_t connection_id,
                           msgs::Type message_type, const uint8_t* buffer,
                           size_t buffer_size, Clock::time_point now) {
        decode_result = msgs::DecodePresentationConnectionOpenRequest(
            buffer, buffer_size, &received_request);
        return ConvertDecodeResult(decode_result);
      }));
  MessageDemuxer::MessageWatch watch = demuxer_.WatchMessageType(
      endpoint_id_, msgs::Type::kPresentationConnectionOpenRequest,
      &mock_callback_);
  ASSERT_TRUE(watch);

  demuxer_.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                        buffer_.size());
  ExpectDecodedRequest(decode_result, received_request);
}

TEST_F(MessageDemuxerTest, WatchAfterMultipleData) {
  MockMessageCallback mock_init_callback;
  msgs::PresentationConnectionOpenRequest received_request;
  msgs::PresentationStartRequest received_init_request;
  ssize_t decode_result1 = 0;
  ssize_t decode_result2 = 0;
  MessageDemuxer::MessageWatch init_watch = demuxer_.WatchMessageType(
      endpoint_id_, msgs::Type::kPresentationStartRequest, &mock_init_callback);
  EXPECT_CALL(
      mock_callback_,
      OnStreamMessage(endpoint_id_, connection_id_,
                      msgs::Type::kPresentationConnectionOpenRequest, _, _, _))
      .WillOnce(Invoke([&decode_result1, &received_request](
                           uint64_t endpoint_id, uint64_t connection_id,
                           msgs::Type message_type, const uint8_t* buffer,
                           size_t buffer_size, Clock::time_point now) {
        decode_result1 = msgs::DecodePresentationConnectionOpenRequest(
            buffer, buffer_size, &received_request);
        return ConvertDecodeResult(decode_result1);
      }));
  EXPECT_CALL(mock_init_callback,
              OnStreamMessage(endpoint_id_, connection_id_,
                              msgs::Type::kPresentationStartRequest, _, _, _))
      .WillOnce(Invoke([&decode_result2, &received_init_request](
                           uint64_t endpoint_id, uint64_t connection_id,
                           msgs::Type message_type, const uint8_t* buffer,
                           size_t buffer_size, Clock::time_point now) {
        decode_result2 = msgs::DecodePresentationStartRequest(
            buffer, buffer_size, &received_init_request);
        return ConvertDecodeResult(decode_result2);
      }));
  MessageDemuxer::MessageWatch watch = demuxer_.WatchMessageType(
      endpoint_id_, msgs::Type::kPresentationConnectionOpenRequest,
      &mock_callback_);
  ASSERT_TRUE(watch);

  demuxer_.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                        buffer_.size());

  msgs::CborEncodeBuffer buffer;
  msgs::PresentationStartRequest request;
  request.request_id = 2;
  request.url = "https://example.com/recv";
  ASSERT_TRUE(msgs::EncodePresentationStartRequest(request, &buffer));
  demuxer_.OnStreamData(endpoint_id_, connection_id_, buffer.data(),
                        buffer.size());

  ExpectDecodedRequest(decode_result1, received_request);
  ASSERT_GT(decode_result2, 0);
  EXPECT_EQ(decode_result2, static_cast<ssize_t>(buffer.size() - 2));
  EXPECT_EQ(request.request_id, received_init_request.request_id);
  EXPECT_EQ(request.url, received_init_request.url);
}

TEST_F(MessageDemuxerTest, GlobalWatchAfterData) {
  msgs::PresentationConnectionOpenRequest received_request;
  ssize_t decode_result = 0;
  EXPECT_CALL(
      mock_callback_,
      OnStreamMessage(endpoint_id_, connection_id_,
                      msgs::Type::kPresentationConnectionOpenRequest, _, _, _))
      .WillOnce(Invoke([&decode_result, &received_request](
                           uint64_t endpoint_id, uint64_t connection_id,
                           msgs::Type message_type, const uint8_t* buffer,
                           size_t buffer_size, Clock::time_point now) {
        decode_result = msgs::DecodePresentationConnectionOpenRequest(
            buffer, buffer_size, &received_request);
        return ConvertDecodeResult(decode_result);
      }));
  MessageDemuxer::MessageWatch watch = demuxer_.SetDefaultMessageTypeWatch(
      msgs::Type::kPresentationConnectionOpenRequest, &mock_callback_);
  ASSERT_TRUE(watch);
  demuxer_.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                        buffer_.size());
  ExpectDecodedRequest(decode_result, received_request);
}

TEST_F(MessageDemuxerTest, BufferLimit) {
  MessageDemuxer demuxer(FakeClock::now, 10);

  demuxer.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                       buffer_.size());
  EXPECT_CALL(mock_callback_, OnStreamMessage(_, _, _, _, _, _)).Times(0);
  MessageDemuxer::MessageWatch watch = demuxer.WatchMessageType(
      endpoint_id_, msgs::Type::kPresentationConnectionOpenRequest,
      &mock_callback_);

  msgs::PresentationConnectionOpenRequest received_request;
  ssize_t decode_result = 0;
  EXPECT_CALL(
      mock_callback_,
      OnStreamMessage(endpoint_id_, connection_id_,
                      msgs::Type::kPresentationConnectionOpenRequest, _, _, _))
      .WillOnce(Invoke([&decode_result, &received_request](
                           uint64_t endpoint_id, uint64_t connection_id,
                           msgs::Type message_type, const uint8_t* buffer,
                           size_t buffer_size, Clock::time_point now) {
        decode_result = msgs::DecodePresentationConnectionOpenRequest(
            buffer, buffer_size, &received_request);
        return ConvertDecodeResult(decode_result);
      }));
  demuxer.OnStreamData(endpoint_id_, connection_id_, buffer_.data(),
                       buffer_.size());
  ExpectDecodedRequest(decode_result, received_request);
}

TEST_F(MessageDemuxerTest, DeserializeMessages) {
  std::vector<uint8_t> kAgentInfoResponseSerialized{0x0B, 0xFF};
  std::vector<uint8_t> kPresentationConnectionCloseEventSerialized{0x40, 0x71,
                                                                   0x00};
  std::vector<uint8_t> kAuthenticationRequestSerialized{0x43, 0xE9, 0xFF, 0x00};

  size_t used_bytes;
  auto kAgentInfoResponseInfo =
      MessageTypeDecoder::DecodeType(kAgentInfoResponseSerialized, &used_bytes);
  EXPECT_FALSE(kAgentInfoResponseInfo.is_error());
  EXPECT_EQ(used_bytes, size_t{1});
  EXPECT_EQ(kAgentInfoResponseInfo.value(), msgs::Type::kAgentInfoResponse);

  auto kPresentationConnectionCloseEventInfo = MessageTypeDecoder::DecodeType(
      kPresentationConnectionCloseEventSerialized, &used_bytes);
  EXPECT_FALSE(kPresentationConnectionCloseEventInfo.is_error());
  EXPECT_EQ(used_bytes, size_t{2});
  EXPECT_EQ(kPresentationConnectionCloseEventInfo.value(),
            msgs::Type::kPresentationConnectionCloseEvent);

  auto kAuthenticationRequestInfo = MessageTypeDecoder::DecodeType(
      kAuthenticationRequestSerialized, &used_bytes);
  EXPECT_FALSE(kAuthenticationRequestInfo.is_error());
  EXPECT_EQ(used_bytes, size_t{2});
  EXPECT_EQ(kAuthenticationRequestInfo.value(),
            msgs::Type::kAuthenticationRequest);

  auto kUnknownInfo = MessageTypeDecoder::DecodeType({0xFF}, &used_bytes);
  EXPECT_TRUE(kUnknownInfo.is_error());
}

}  // namespace osp
}  // namespace openscreen
