// 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/cast_channel/cast_message_handler.h"

#include "base/json/json_reader.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/test_simple_task_runner.h"
#include "components/cast_channel/cast_test_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "services/data_decoder/public/cpp/testing_json_parser.h"
#include "services/service_manager/public/cpp/connector.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::SaveArg;

namespace cast_channel {

namespace {

constexpr char kTestUserAgentString[] =
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
    "Chrome/66.0.3331.0 Safari/537.36";
constexpr char kSourceId[] = "sourceId";
constexpr char kDestinationId[] = "destinationId";

std::unique_ptr<base::Value> GetDictionaryFromCastMessage(
    const CastMessage& message) {
  if (!message.has_payload_utf8())
    return nullptr;

  return base::JSONReader::Read(message.payload_utf8());
}

CastMessageType GetMessageType(const CastMessage& message) {
  std::unique_ptr<base::Value> dict = GetDictionaryFromCastMessage(message);
  if (!dict)
    return CastMessageType::kOther;

  const base::Value* message_type =
      dict->FindKeyOfType("type", base::Value::Type::STRING);
  if (!message_type)
    return CastMessageType::kOther;

  return CastMessageTypeFromString(message_type->GetString());
}

}  // namespace

class CastMessageHandlerTest : public testing::Test {
 public:
  CastMessageHandlerTest()
      : thread_bundle_(
            base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
        cast_socket_service_(new base::TestSimpleTaskRunner()),
        handler_(&cast_socket_service_,
                 /* connector */ nullptr,
                 base::Token{1, 1},
                 kTestUserAgentString,
                 "66.0.3331.0",
                 "en-US") {
    ON_CALL(cast_socket_service_, GetSocket(_))
        .WillByDefault(testing::Return(&cast_socket_));
  }

  ~CastMessageHandlerTest() override {}

  void OnMessage(const CastMessage& message) {
    handler_.OnMessage(cast_socket_, message);
  }

  void OnError(ChannelError error) { handler_.OnError(cast_socket_, error); }

  void OnAppAvailability(const std::string& app_id,
                         GetAppAvailabilityResult result) {
    if (run_loop_)
      run_loop_->Quit();
    DoOnAppAvailability(app_id, result);
  }

  MOCK_METHOD2(DoOnAppAvailability,
               void(const std::string& app_id,
                    GetAppAvailabilityResult result));

  void ExpectSessionLaunchResult(LaunchSessionResponse::Result expected_result,
                                 LaunchSessionResponse response) {
    if (run_loop_)
      run_loop_->Quit();
    ++session_launch_response_count_;
    EXPECT_EQ(expected_result, response.result);
    if (response.result == LaunchSessionResponse::Result::kOk)
      EXPECT_TRUE(response.receiver_status);
  }

 protected:
  content::TestBrowserThreadBundle thread_bundle_;
  std::unique_ptr<base::RunLoop> run_loop_;
  MockCastSocketService cast_socket_service_;
  data_decoder::TestingJsonParser::ScopedFactoryOverride parser_override_;
  CastMessageHandler handler_;
  MockCastSocket cast_socket_;
  int session_launch_response_count_ = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(CastMessageHandlerTest);
};

TEST_F(CastMessageHandlerTest, VirtualConnectionCreatedOnlyOnce) {
  CastMessage virtual_connection_request;
  CastMessage app_availability_request1;
  CastMessage app_availability_request2;
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _))
      .WillOnce(SaveArg<0>(&virtual_connection_request))
      .WillOnce(SaveArg<0>(&app_availability_request1))
      .WillOnce(SaveArg<0>(&app_availability_request2));

  handler_.RequestAppAvailability(
      &cast_socket_, "AAAAAAAA",
      base::BindOnce(&CastMessageHandlerTest::OnAppAvailability,
                     base::Unretained(this)));
  handler_.RequestAppAvailability(
      &cast_socket_, "BBBBBBBB",
      base::BindOnce(&CastMessageHandlerTest::OnAppAvailability,
                     base::Unretained(this)));

  EXPECT_EQ(CastMessageType::kConnect,
            GetMessageType(virtual_connection_request));
  EXPECT_EQ(CastMessageType::kGetAppAvailability,
            GetMessageType(app_availability_request1));
  EXPECT_EQ(CastMessageType::kGetAppAvailability,
            GetMessageType(app_availability_request2));
}

TEST_F(CastMessageHandlerTest, RecreateVirtualConnectionAfterError) {
  CastMessage virtual_connection_request;
  CastMessage app_availability_request;
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _))
      .WillOnce(SaveArg<0>(&virtual_connection_request))
      .WillOnce(SaveArg<0>(&app_availability_request));

  handler_.RequestAppAvailability(
      &cast_socket_, "AAAAAAAA",
      base::BindOnce(&CastMessageHandlerTest::OnAppAvailability,
                     base::Unretained(this)));
  EXPECT_EQ(CastMessageType::kConnect,
            GetMessageType(virtual_connection_request));
  EXPECT_EQ(CastMessageType::kGetAppAvailability,
            GetMessageType(app_availability_request));

  EXPECT_CALL(*this, DoOnAppAvailability("AAAAAAAA",
                                         GetAppAvailabilityResult::kUnknown));
  OnError(ChannelError::TRANSPORT_ERROR);

  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _))
      .WillOnce(SaveArg<0>(&virtual_connection_request))
      .WillOnce(SaveArg<0>(&app_availability_request));

  handler_.RequestAppAvailability(
      &cast_socket_, "BBBBBBBB",
      base::BindOnce(&CastMessageHandlerTest::OnAppAvailability,
                     base::Unretained(this)));

  EXPECT_EQ(CastMessageType::kConnect,
            GetMessageType(virtual_connection_request));
  EXPECT_EQ(CastMessageType::kGetAppAvailability,
            GetMessageType(app_availability_request));
  // The callback is invoked with kUnknown before the PendingRequests is
  // destroyed.
  EXPECT_CALL(*this, DoOnAppAvailability("BBBBBBBB",
                                         GetAppAvailabilityResult::kUnknown));
}

TEST_F(CastMessageHandlerTest, RequestAppAvailability) {
  CastMessage virtual_connection_request;
  CastMessage app_availability_request;
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _))
      .WillOnce(SaveArg<0>(&virtual_connection_request))
      .WillOnce(SaveArg<0>(&app_availability_request));

  handler_.RequestAppAvailability(
      &cast_socket_, "ABCDEFAB",
      base::BindOnce(&CastMessageHandlerTest::OnAppAvailability,
                     base::Unretained(this)));

  EXPECT_EQ(CastMessageType::kConnect,
            GetMessageType(virtual_connection_request));
  EXPECT_EQ(CastMessageType::kGetAppAvailability,
            GetMessageType(app_availability_request));

  std::unique_ptr<base::Value> dict =
      GetDictionaryFromCastMessage(app_availability_request);
  ASSERT_TRUE(dict);
  const base::Value* request_id_value =
      dict->FindKeyOfType("requestId", base::Value::Type::INTEGER);
  ASSERT_TRUE(request_id_value);
  int request_id = request_id_value->GetInt();
  EXPECT_GT(request_id, 0);

  CastMessage response;
  response.set_namespace_("urn:x-cast:com.google.cast.receiver");
  response.set_source_id("receiver-0");
  response.set_destination_id(handler_.sender_id());
  response.set_payload_type(
      CastMessage::PayloadType::CastMessage_PayloadType_STRING);
  response.set_payload_utf8(
      base::StringPrintf("{\"requestId\": %d, \"availability\": {\"ABCDEFAB\": "
                         "\"APP_AVAILABLE\"}}",
                         request_id));

  run_loop_ = std::make_unique<base::RunLoop>();
  EXPECT_CALL(*this, DoOnAppAvailability("ABCDEFAB",
                                         GetAppAvailabilityResult::kAvailable));
  OnMessage(response);
  run_loop_->Run();
}

TEST_F(CastMessageHandlerTest, RequestAppAvailabilityTimesOut) {
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _)).Times(2);
  handler_.RequestAppAvailability(
      &cast_socket_, "ABCDEFAB",
      base::BindOnce(&CastMessageHandlerTest::OnAppAvailability,
                     base::Unretained(this)));
  EXPECT_CALL(*this, DoOnAppAvailability("ABCDEFAB",
                                         GetAppAvailabilityResult::kUnknown));
  thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(5));
}

TEST_F(CastMessageHandlerTest, AppAvailabilitySentOnlyOnceWhilePending) {
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _)).Times(2);
  handler_.RequestAppAvailability(
      &cast_socket_, "ABCDEFAB",
      base::BindOnce(&CastMessageHandlerTest::OnAppAvailability,
                     base::Unretained(this)));

  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _)).Times(0);
  handler_.RequestAppAvailability(
      &cast_socket_, "ABCDEFAB",
      base::BindOnce(&CastMessageHandlerTest::OnAppAvailability,
                     base::Unretained(this)));
}

TEST_F(CastMessageHandlerTest, EnsureConnection) {
  CastMessage virtual_connection_request;
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _))
      .WillOnce(SaveArg<0>(&virtual_connection_request));

  handler_.EnsureConnection(cast_socket_.id(), kSourceId, kDestinationId);
  EXPECT_EQ(CastMessageType::kConnect,
            GetMessageType(virtual_connection_request));

  // No-op because connection is already created the first time.
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _)).Times(0);
  handler_.EnsureConnection(cast_socket_.id(), kSourceId, kDestinationId);
}

TEST_F(CastMessageHandlerTest, CloseConnectionFromReceiver) {
  CastMessage virtual_connection_request;
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _));
  handler_.EnsureConnection(cast_socket_.id(), kSourceId, kDestinationId);

  CastMessage response;
  response.set_namespace_("urn:x-cast:com.google.cast.tp.connection");
  response.set_source_id(kDestinationId);
  response.set_destination_id(kSourceId);
  response.set_payload_type(
      CastMessage::PayloadType::CastMessage_PayloadType_STRING);
  response.set_payload_utf8(R"({
      "type": "CLOSE"
  })");
  OnMessage(response);
  // Wait for message to be parsed and handled.
  thread_bundle_.RunUntilIdle();

  // Re-open virtual connection should cause message to be sent.
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _));
  handler_.EnsureConnection(cast_socket_.id(), kSourceId, kDestinationId);
}

TEST_F(CastMessageHandlerTest, LaunchSession) {
  CastMessage virtual_connection_request;
  CastMessage launch_session_request;
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _))
      .WillOnce(SaveArg<0>(&virtual_connection_request))
      .WillOnce(SaveArg<0>(&launch_session_request));

  handler_.LaunchSession(
      cast_socket_.id(), "AAAAAAAA", base::TimeDelta::FromSeconds(30),
      base::BindOnce(&CastMessageHandlerTest::ExpectSessionLaunchResult,
                     base::Unretained(this),
                     LaunchSessionResponse::Result::kOk));
  EXPECT_EQ(CastMessageType::kConnect,
            GetMessageType(virtual_connection_request));
  EXPECT_EQ(CastMessageType::kLaunch, GetMessageType(launch_session_request));

  std::unique_ptr<base::Value> dict =
      GetDictionaryFromCastMessage(launch_session_request);
  ASSERT_TRUE(dict);
  const base::Value* request_id_value =
      dict->FindKeyOfType("requestId", base::Value::Type::INTEGER);
  ASSERT_TRUE(request_id_value);
  int request_id = request_id_value->GetInt();
  EXPECT_GT(request_id, 0);

  CastMessage response;
  response.set_namespace_("urn:x-cast:com.google.cast.receiver");
  response.set_source_id("receiver-0");
  response.set_destination_id(handler_.sender_id());
  response.set_payload_type(
      CastMessage::PayloadType::CastMessage_PayloadType_STRING);
  response.set_payload_utf8(
      base::StringPrintf("{"
                         "\"type\": \"RECEIVER_STATUS\","
                         "\"requestId\": %d,"
                         "\"status\": {}"
                         "}",
                         request_id));

  run_loop_ = std::make_unique<base::RunLoop>();
  OnMessage(response);
  run_loop_->Run();
  EXPECT_EQ(1, session_launch_response_count_);
}

TEST_F(CastMessageHandlerTest, LaunchSessionTimedOut) {
  CastMessage virtual_connection_request;
  CastMessage launch_session_request;
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _))
      .WillOnce(SaveArg<0>(&virtual_connection_request))
      .WillOnce(SaveArg<0>(&launch_session_request));

  handler_.LaunchSession(
      cast_socket_.id(), "AAAAAAAA", base::TimeDelta::FromSeconds(30),
      base::BindOnce(&CastMessageHandlerTest::ExpectSessionLaunchResult,
                     base::Unretained(this),
                     LaunchSessionResponse::Result::kTimedOut));
  EXPECT_EQ(CastMessageType::kConnect,
            GetMessageType(virtual_connection_request));
  EXPECT_EQ(CastMessageType::kLaunch, GetMessageType(launch_session_request));

  thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(30));
  EXPECT_EQ(1, session_launch_response_count_);
}

TEST_F(CastMessageHandlerTest, SendAppMessage) {
  CastMessage virtual_connection_request;
  CastMessage app_message;
  EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _))
      .WillOnce(SaveArg<0>(&virtual_connection_request))
      .WillOnce(SaveArg<0>(&app_message));

  base::Value body(base::Value::Type::DICTIONARY);
  body.SetKey("foo", base::Value("bar"));
  CastMessage message =
      CreateCastMessage("namespace", body, kSourceId, kDestinationId);
  handler_.SendAppMessage(cast_socket_.id(), message);

  EXPECT_EQ(CastMessageType::kConnect,
            GetMessageType(virtual_connection_request));
  EXPECT_EQ(message.payload_utf8(), app_message.payload_utf8());
}

}  // namespace cast_channel
