// Copyright 2016 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 <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/protocol_mock_objects.h"
#include "remoting/protocol/validating_authenticator.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"

namespace remoting {
namespace protocol {

namespace {

using testing::_;
using testing::Return;

typedef ValidatingAuthenticator::Result ValidationResult;

constexpr char kRemoteTestJid[] = "ficticious_jid_for_testing";

// testing::InvokeArgument<N> does not work with base::Callback, fortunately
// gmock makes it simple to create action templates that do for the various
// possible numbers of arguments.
ACTION_TEMPLATE(InvokeCallbackArgument,
                HAS_1_TEMPLATE_PARAMS(int, k),
                AND_0_VALUE_PARAMS()) {
  ::std::tr1::get<k>(args).Run();
}

}  // namespace

class ValidatingAuthenticatorTest : public testing::Test {
 public:
  ValidatingAuthenticatorTest();
  ~ValidatingAuthenticatorTest() override;

  void ValidateCallback(
      const std::string& remote_jid,
      const ValidatingAuthenticator::ResultCallback& callback);

 protected:
  // testing::Test overrides.
  void SetUp() override;

  // Calls ProcessMessage() on |validating_authenticator_| and blocks until
  // the result callback is called.
  void SendMessageAndWaitForCallback();

  // Used to set up our mock behaviors on the MockAuthenticator object passed
  // to |validating_authenticator_|.  Lifetime of the object is controlled by
  // |validating_authenticator_| so this pointer is no longer valid once
  // the owner is destroyed.
  testing::NiceMock<MockAuthenticator>* mock_authenticator_ = nullptr;

  // This member is used to drive behavior in |validating_authenticator_| when
  // its validation complete callback is run.
  ValidationResult validation_result_ = ValidationResult::SUCCESS;

  // Tracks whether our validation callback has been called or not.
  bool validate_complete_called_ = false;

  // The object under test.
  std::unique_ptr<ValidatingAuthenticator> validating_authenticator_;

 private:
  base::MessageLoop message_loop_;

  DISALLOW_COPY_AND_ASSIGN(ValidatingAuthenticatorTest);
};

ValidatingAuthenticatorTest::ValidatingAuthenticatorTest() = default;

ValidatingAuthenticatorTest::~ValidatingAuthenticatorTest() = default;

void ValidatingAuthenticatorTest::ValidateCallback(
    const std::string& remote_jid,
    const ValidatingAuthenticator::ResultCallback& callback) {
  validate_complete_called_ = true;
  callback.Run(validation_result_);
}

void ValidatingAuthenticatorTest::SetUp() {
  mock_authenticator_ = new testing::NiceMock<MockAuthenticator>();
  std::unique_ptr<Authenticator> authenticator(mock_authenticator_);

  validating_authenticator_.reset(new ValidatingAuthenticator(
      kRemoteTestJid, base::Bind(&ValidatingAuthenticatorTest::ValidateCallback,
                                 base::Unretained(this)),
      std::move(authenticator)));
}

void ValidatingAuthenticatorTest::SendMessageAndWaitForCallback() {
  base::RunLoop run_loop;
  std::unique_ptr<buzz::XmlElement> first_message(
      Authenticator::CreateEmptyAuthenticatorMessage());
  validating_authenticator_->ProcessMessage(first_message.get(),
                                            run_loop.QuitClosure());
  run_loop.Run();
}

TEST_F(ValidatingAuthenticatorTest, ValidConnection_SingleMessage) {
  EXPECT_CALL(*mock_authenticator_, ProcessMessage(_, _))
      .Times(1)
      .WillOnce(InvokeCallbackArgument<1>());

  ON_CALL(*mock_authenticator_, state())
      .WillByDefault(Return(Authenticator::ACCEPTED));

  SendMessageAndWaitForCallback();
  ASSERT_TRUE(validate_complete_called_);
  ASSERT_EQ(Authenticator::ACCEPTED, validating_authenticator_->state());
}

TEST_F(ValidatingAuthenticatorTest, ValidConnection_TwoMessages) {
  // Send the first message to the authenticator, set the mock up to act
  // like it is waiting for a second message.
  EXPECT_CALL(*mock_authenticator_, ProcessMessage(_, _))
      .Times(2)
      .WillRepeatedly(InvokeCallbackArgument<1>());

  EXPECT_CALL(*mock_authenticator_, state())
      .WillRepeatedly(Return(Authenticator::MESSAGE_READY));

  SendMessageAndWaitForCallback();
  ASSERT_FALSE(validate_complete_called_);
  ASSERT_EQ(Authenticator::MESSAGE_READY, validating_authenticator_->state());

  // Now 'retrieve' the message for the client which resets the state.
  EXPECT_CALL(*mock_authenticator_, state())
      .WillRepeatedly(Return(Authenticator::WAITING_MESSAGE));

  // This dance is needed because GMock doesn't handle unique_ptrs very well.
  // The mock method receives a raw pointer which it wraps and returns when
  // GetNextMessage() is called.
  std::unique_ptr<buzz::XmlElement> next_message(
      Authenticator::CreateEmptyAuthenticatorMessage());
  EXPECT_CALL(*mock_authenticator_, GetNextMessagePtr())
      .Times(1)
      .WillOnce(Return(next_message.release()));

  validating_authenticator_->GetNextMessage();
  ASSERT_EQ(Authenticator::WAITING_MESSAGE, validating_authenticator_->state());

  // Now send the second message for processing.
  EXPECT_CALL(*mock_authenticator_, state())
      .WillRepeatedly(Return(Authenticator::ACCEPTED));

  SendMessageAndWaitForCallback();
  ASSERT_TRUE(validate_complete_called_);
  ASSERT_EQ(Authenticator::ACCEPTED, validating_authenticator_->state());
}

TEST_F(ValidatingAuthenticatorTest, ValidConnection_SendBeforeAccept) {
  // This test simulates an authenticator which needs to send a message before
  // transitioning to the ACCEPTED state.
  EXPECT_CALL(*mock_authenticator_, ProcessMessage(_, _))
      .Times(1)
      .WillRepeatedly(InvokeCallbackArgument<1>());

  EXPECT_CALL(*mock_authenticator_, state())
      .WillOnce(Return(Authenticator::MESSAGE_READY))
      .WillOnce(Return(Authenticator::ACCEPTED));

  // This dance is needed because GMock doesn't handle unique_ptrs very well.
  // The mock method receives a raw pointer which it wraps and returns when
  // GetNextMessage() is called.
  std::unique_ptr<buzz::XmlElement> next_message(
      Authenticator::CreateEmptyAuthenticatorMessage());
  EXPECT_CALL(*mock_authenticator_, GetNextMessagePtr())
      .Times(1)
      .WillOnce(Return(next_message.release()));

  SendMessageAndWaitForCallback();
  ASSERT_TRUE(validate_complete_called_);
  ASSERT_EQ(Authenticator::MESSAGE_READY, validating_authenticator_->state());

  // Now 'retrieve' the message for the client which resets the state.
  validating_authenticator_->GetNextMessage();
  ASSERT_EQ(Authenticator::ACCEPTED, validating_authenticator_->state());
}

TEST_F(ValidatingAuthenticatorTest, ValidConnection_ErrorInvalidCredentials) {
  EXPECT_CALL(*mock_authenticator_, ProcessMessage(_, _))
      .Times(1)
      .WillOnce(InvokeCallbackArgument<1>());

  ON_CALL(*mock_authenticator_, state())
      .WillByDefault(Return(Authenticator::ACCEPTED));

  validation_result_ = ValidationResult::ERROR_INVALID_CREDENTIALS;

  SendMessageAndWaitForCallback();
  ASSERT_TRUE(validate_complete_called_);
  ASSERT_EQ(Authenticator::REJECTED, validating_authenticator_->state());
  ASSERT_EQ(Authenticator::INVALID_CREDENTIALS,
            validating_authenticator_->rejection_reason());
}

TEST_F(ValidatingAuthenticatorTest, ValidConnection_ErrorRejectedByUser) {
  EXPECT_CALL(*mock_authenticator_, ProcessMessage(_, _))
      .Times(1)
      .WillOnce(InvokeCallbackArgument<1>());

  ON_CALL(*mock_authenticator_, state())
      .WillByDefault(Return(Authenticator::ACCEPTED));

  validation_result_ = ValidationResult::ERROR_REJECTED_BY_USER;

  SendMessageAndWaitForCallback();
  ASSERT_TRUE(validate_complete_called_);
  ASSERT_EQ(Authenticator::REJECTED, validating_authenticator_->state());
  ASSERT_EQ(Authenticator::REJECTED_BY_USER,
            validating_authenticator_->rejection_reason());
}

TEST_F(ValidatingAuthenticatorTest, ValidConnection_ErrorTooManyConnections) {
  EXPECT_CALL(*mock_authenticator_, ProcessMessage(_, _))
      .Times(1)
      .WillOnce(InvokeCallbackArgument<1>());

  ON_CALL(*mock_authenticator_, state())
      .WillByDefault(Return(Authenticator::ACCEPTED));

  validation_result_ = ValidationResult::ERROR_TOO_MANY_CONNECTIONS;

  SendMessageAndWaitForCallback();
  ASSERT_TRUE(validate_complete_called_);
  ASSERT_EQ(Authenticator::REJECTED, validating_authenticator_->state());
  ASSERT_EQ(Authenticator::TOO_MANY_CONNECTIONS,
            validating_authenticator_->rejection_reason());
}

TEST_F(ValidatingAuthenticatorTest, InvalidConnection_InvalidCredentials) {
  EXPECT_CALL(*mock_authenticator_, ProcessMessage(_, _))
      .Times(1)
      .WillOnce(InvokeCallbackArgument<1>());

  ON_CALL(*mock_authenticator_, state())
      .WillByDefault(Return(Authenticator::REJECTED));

  ON_CALL(*mock_authenticator_, rejection_reason())
      .WillByDefault(Return(Authenticator::INVALID_CREDENTIALS));

  // Verify validation callback is not called for invalid connections.
  SendMessageAndWaitForCallback();
  ASSERT_FALSE(validate_complete_called_);
  ASSERT_EQ(Authenticator::REJECTED, validating_authenticator_->state());
  ASSERT_EQ(Authenticator::INVALID_CREDENTIALS,
            validating_authenticator_->rejection_reason());
}

TEST_F(ValidatingAuthenticatorTest, InvalidConnection_InvalidAccount) {
  EXPECT_CALL(*mock_authenticator_, ProcessMessage(_, _))
      .Times(1)
      .WillOnce(InvokeCallbackArgument<1>());

  ON_CALL(*mock_authenticator_, state())
      .WillByDefault(Return(Authenticator::REJECTED));

  ON_CALL(*mock_authenticator_, rejection_reason())
      .WillByDefault(Return(Authenticator::INVALID_ACCOUNT));

  // Verify validation callback is not called for invalid connections.
  SendMessageAndWaitForCallback();
  ASSERT_FALSE(validate_complete_called_);
  ASSERT_EQ(Authenticator::REJECTED, validating_authenticator_->state());
  ASSERT_EQ(Authenticator::INVALID_ACCOUNT,
            validating_authenticator_->rejection_reason());
}

TEST_F(ValidatingAuthenticatorTest, InvalidConnection_ProtocolError) {
  EXPECT_CALL(*mock_authenticator_, ProcessMessage(_, _))
      .Times(1)
      .WillOnce(InvokeCallbackArgument<1>());

  ON_CALL(*mock_authenticator_, state())
      .WillByDefault(Return(Authenticator::REJECTED));

  ON_CALL(*mock_authenticator_, rejection_reason())
      .WillByDefault(Return(Authenticator::PROTOCOL_ERROR));

  // Verify validation callback is not called for invalid connections.
  SendMessageAndWaitForCallback();
  ASSERT_FALSE(validate_complete_called_);
  ASSERT_EQ(Authenticator::REJECTED, validating_authenticator_->state());
  ASSERT_EQ(Authenticator::PROTOCOL_ERROR,
            validating_authenticator_->rejection_reason());
}

}  // namespace protocol
}  // namespace remoting
