// 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 "components/mirroring/service/message_dispatcher.h"

#include "base/base64.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::InvokeWithoutArgs;
using ::testing::_;
using mirroring::mojom::CastMessage;
using mirroring::mojom::CastMessagePtr;

namespace mirroring {

namespace {

bool IsEqual(const CastMessage& message1, const CastMessage& message2) {
  return message1.message_namespace == message2.message_namespace &&
         message1.json_format_data == message2.json_format_data;
}

void CloneResponse(const ReceiverResponse& response,
                   ReceiverResponse* cloned_response) {
  cloned_response->type = response.type;
  cloned_response->session_id = response.session_id;
  cloned_response->sequence_number = response.sequence_number;
  cloned_response->result = response.result;
  if (response.answer)
    cloned_response->answer = std::make_unique<Answer>(*response.answer);
  if (response.status)
    cloned_response->status =
        std::make_unique<ReceiverStatus>(*response.status);
  if (response.capabilities) {
    cloned_response->capabilities =
        std::make_unique<ReceiverCapability>(*response.capabilities);
  }
  cloned_response->rpc = response.rpc;
  if (response.error) {
    cloned_response->error = std::make_unique<ReceiverError>();
    cloned_response->error->code = response.error->code;
    cloned_response->error->description = response.error->description;
    cloned_response->error->details = response.error->details;
  }
}

}  // namespace

class MessageDispatcherTest : public mojom::CastMessageChannel,
                              public ::testing::Test {
 public:
  MessageDispatcherTest() : binding_(this) {
    mojom::CastMessageChannelPtr outbound_channel;
    binding_.Bind(mojo::MakeRequest(&outbound_channel));
    message_dispatcher_ = std::make_unique<MessageDispatcher>(
        std::move(outbound_channel), mojo::MakeRequest(&inbound_channel_),
        base::BindRepeating(&MessageDispatcherTest::OnParsingError,
                            base::Unretained(this)));
    message_dispatcher_->Subscribe(
        ResponseType::ANSWER,
        base::BindRepeating(&MessageDispatcherTest::OnAnswerResponse,
                            base::Unretained(this)));
    message_dispatcher_->Subscribe(
        ResponseType::STATUS_RESPONSE,
        base::BindRepeating(&MessageDispatcherTest::OnStatusResponse,
                            base::Unretained(this)));
  }
  ~MessageDispatcherTest() override { scoped_task_environment_.RunUntilIdle(); }

  void OnParsingError(const std::string& error_message) {
    last_error_message_ = error_message;
  }

  void OnAnswerResponse(const ReceiverResponse& response) {
    if (!last_answer_response_)
      last_answer_response_ = std::make_unique<ReceiverResponse>();
    CloneResponse(response, last_answer_response_.get());
  }

  void OnStatusResponse(const ReceiverResponse& response) {
    if (!last_status_response_)
      last_status_response_ = std::make_unique<ReceiverResponse>();
    CloneResponse(response, last_status_response_.get());
  }

 protected:
  // mojom::CastMessageChannel implementation. Handles outbound message.
  void Send(mojom::CastMessagePtr message) override {
    last_outbound_message_.message_namespace = message->message_namespace;
    last_outbound_message_.json_format_data = message->json_format_data;
  }

  // Simulates receiving an inbound message from receiver.
  void SendInboundMessage(const mojom::CastMessage& message) {
    inbound_channel_->Send(message.Clone());
  }

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  std::unique_ptr<MessageDispatcher> message_dispatcher_;
  CastMessage last_outbound_message_;
  std::string last_error_message_;
  std::unique_ptr<ReceiverResponse> last_answer_response_;
  std::unique_ptr<ReceiverResponse> last_status_response_;

 private:
  mojo::Binding<mojom::CastMessageChannel> binding_;
  mojom::CastMessageChannelPtr inbound_channel_;
  DISALLOW_COPY_AND_ASSIGN(MessageDispatcherTest);
};

TEST_F(MessageDispatcherTest, SendsOutboundMessage) {
  const std::string test1 = "{\"a\": 1, \"b\": 2}";
  const CastMessage message1 = CastMessage{mojom::kWebRtcNamespace, test1};
  message_dispatcher_->SendOutboundMessage(message1.Clone());
  scoped_task_environment_.RunUntilIdle();
  EXPECT_TRUE(IsEqual(message1, last_outbound_message_));
  EXPECT_TRUE(last_error_message_.empty());

  const std::string test2 = "{\"m\": 99, \"i\": 98, \"u\": 97}";
  const CastMessage message2 = CastMessage{mojom::kWebRtcNamespace, test2};
  message_dispatcher_->SendOutboundMessage(message2.Clone());
  scoped_task_environment_.RunUntilIdle();
  EXPECT_TRUE(IsEqual(message2, last_outbound_message_));
  EXPECT_TRUE(last_error_message_.empty());
}

TEST_F(MessageDispatcherTest, DispatchMessageToSubscriber) {
  // Simulate a receiver ANSWER response and expect that just the ANSWER
  // subscriber processes the message.
  const std::string answer_response =
      "{\"type\":\"ANSWER\",\"seqNum\":12345,\"result\":\"ok\","
      "\"answer\":{\"udpPort\":50691}}";
  const CastMessage answer_message =
      CastMessage{mojom::kWebRtcNamespace, answer_response};
  SendInboundMessage(answer_message);
  scoped_task_environment_.RunUntilIdle();
  ASSERT_TRUE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  EXPECT_EQ(12345, last_answer_response_->sequence_number);
  EXPECT_EQ(ResponseType::ANSWER, last_answer_response_->type);
  EXPECT_EQ("ok", last_answer_response_->result);
  EXPECT_EQ(50691, last_answer_response_->answer->udp_port);
  EXPECT_FALSE(last_answer_response_->status);
  last_answer_response_.reset();
  EXPECT_TRUE(last_error_message_.empty());

  // Simulate a receiver STATUS_RESPONSE and expect that just the
  // STATUS_RESPONSE subscriber processes the message.
  const std::string status_response =
      "{\"type\":\"STATUS_RESPONSE\",\"seqNum\":12345,\"result\":\"ok\","
      "\"status\":{\"wifiSnr\":42}}";
  const CastMessage status_message =
      CastMessage{mojom::kWebRtcNamespace, status_response};
  SendInboundMessage(status_message);
  scoped_task_environment_.RunUntilIdle();
  EXPECT_FALSE(last_answer_response_);
  ASSERT_TRUE(last_status_response_);
  EXPECT_EQ(12345, last_status_response_->sequence_number);
  EXPECT_EQ(ResponseType::STATUS_RESPONSE, last_status_response_->type);
  EXPECT_EQ("ok", last_status_response_->result);
  EXPECT_EQ(42, last_status_response_->status->wifi_snr);
  last_status_response_.reset();
  EXPECT_TRUE(last_error_message_.empty());

  // Unsubscribe from ANSWER messages, and when feeding-in an ANSWER message,
  // nothing should happen.
  message_dispatcher_->Unsubscribe(ResponseType::ANSWER);
  SendInboundMessage(answer_message);
  scoped_task_environment_.RunUntilIdle();
  EXPECT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  EXPECT_FALSE(last_error_message_.empty());  // Expect an error reported.
  last_error_message_.clear();

  // However, STATUS_RESPONSE messages should still be dispatcher to the
  // remaining subscriber.
  SendInboundMessage(status_message);
  scoped_task_environment_.RunUntilIdle();
  EXPECT_FALSE(last_answer_response_);
  EXPECT_TRUE(last_status_response_);
  last_status_response_.reset();
  EXPECT_TRUE(last_error_message_.empty());

  // Finally, unsubscribe from STATUS_RESPONSE messages, and when feeding-in
  // either an ANSWER or a STATUS_RESPONSE message, nothing should happen.
  message_dispatcher_->Unsubscribe(ResponseType::STATUS_RESPONSE);
  SendInboundMessage(answer_message);
  scoped_task_environment_.RunUntilIdle();
  EXPECT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  EXPECT_FALSE(last_error_message_.empty());
  last_error_message_.clear();
  SendInboundMessage(status_message);
  scoped_task_environment_.RunUntilIdle();
  EXPECT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  EXPECT_FALSE(last_error_message_.empty());
}

TEST_F(MessageDispatcherTest, IgnoreMalformedMessage) {
  const CastMessage message =
      CastMessage{mojom::kWebRtcNamespace, "MUAHAHAHAHAHAHAHA!"};
  SendInboundMessage(message);
  scoped_task_environment_.RunUntilIdle();
  EXPECT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  EXPECT_FALSE(last_error_message_.empty());
}

TEST_F(MessageDispatcherTest, IgnoreMessageWithWrongNamespace) {
  const std::string answer_response =
      "{\"type\":\"ANSWER\",\"seqNum\":12345,\"result\":\"ok\","
      "\"answer\":{\"udpPort\":50691}}";
  const CastMessage answer_message =
      CastMessage{"Wrong_namespace", answer_response};
  SendInboundMessage(answer_message);
  scoped_task_environment_.RunUntilIdle();
  EXPECT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  // Messages with different namespace are ignored with no error reported.
  EXPECT_TRUE(last_error_message_.empty());
}

TEST_F(MessageDispatcherTest, RequestReply) {
  EXPECT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  message_dispatcher_->Unsubscribe(ResponseType::ANSWER);
  scoped_task_environment_.RunUntilIdle();
  const std::string fake_offer = "{\"type\":\"OFFER\",\"seqNum\":45623}";
  const CastMessage offer_message =
      CastMessage{mojom::kWebRtcNamespace, fake_offer};
  message_dispatcher_->RequestReply(
      offer_message.Clone(), ResponseType::ANSWER, 45623,
      base::TimeDelta::FromMilliseconds(100),
      base::BindRepeating(&MessageDispatcherTest::OnAnswerResponse,
                          base::Unretained(this)));
  scoped_task_environment_.RunUntilIdle();
  // Received the request to send the outbound message.
  EXPECT_TRUE(IsEqual(offer_message, last_outbound_message_));

  std::string answer_response =
      "{\"type\":\"ANSWER\",\"seqNum\":12345,\"result\":\"ok\","
      "\"answer\":{\"udpPort\":50691}}";
  CastMessage answer_message =
      CastMessage{mojom::kWebRtcNamespace, answer_response};
  SendInboundMessage(answer_message);
  scoped_task_environment_.RunUntilIdle();
  // The answer message with mismatched sequence number is ignored.
  EXPECT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  EXPECT_TRUE(last_error_message_.empty());

  answer_response =
      "{\"type\":\"ANSWER\",\"seqNum\":45623,\"result\":\"ok\","
      "\"answer\":{\"udpPort\":50691}}";
  answer_message = CastMessage{mojom::kWebRtcNamespace, answer_response};
  SendInboundMessage(answer_message);
  scoped_task_environment_.RunUntilIdle();
  ASSERT_TRUE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  EXPECT_TRUE(last_error_message_.empty());
  EXPECT_EQ(45623, last_answer_response_->sequence_number);
  EXPECT_EQ(ResponseType::ANSWER, last_answer_response_->type);
  EXPECT_EQ("ok", last_answer_response_->result);
  EXPECT_EQ(50691, last_answer_response_->answer->udp_port);
  last_answer_response_.reset();

  // Expect that the callback for ANSWER message was already unsubscribed.
  SendInboundMessage(answer_message);
  scoped_task_environment_.RunUntilIdle();
  EXPECT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
  EXPECT_FALSE(last_error_message_.empty());
  last_error_message_.clear();

  const CastMessage fake_message = CastMessage{
      mojom::kWebRtcNamespace, "{\"type\":\"OFFER\",\"seqNum\":12345}"};
  message_dispatcher_->RequestReply(
      fake_message.Clone(), ResponseType::ANSWER, 12345,
      base::TimeDelta::FromMilliseconds(100),
      base::BindRepeating(&MessageDispatcherTest::OnAnswerResponse,
                          base::Unretained(this)));
  scoped_task_environment_.RunUntilIdle();
  // Received the request to send the outbound message.
  EXPECT_TRUE(IsEqual(fake_message, last_outbound_message_));
  EXPECT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);

  // Destroy the dispatcher.
  message_dispatcher_.reset();
  scoped_task_environment_.RunUntilIdle();
  ASSERT_FALSE(last_answer_response_);
  EXPECT_FALSE(last_status_response_);
}

}  // namespace mirroring
