// Copyright 2014 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 "chromeos/cryptohome/homedir_methods.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "chromeos/dbus/cryptohome/rpc.pb.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/dbus_method_call_status.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/mock_cryptohome_client.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

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

namespace cryptohome {

namespace {

MATCHER_P(EqualsProto, expected_proto, "") {
  std::string expected_value;
  expected_proto.SerializeToString(&expected_value);
  std::string actual_value;
  arg.SerializeToString(&actual_value);
  return actual_value == expected_value;
}

}  // namespace

const char kUserID[] = "user@example.com";
const char kKeyLabel[] = "key_label";

const int64 kKeyRevision = 123;
const char kProviderData1Name[] = "data_1";
const int64 kProviderData1Number = 12345;
const char kProviderData2Name[] = "data_2";
const char kProviderData2Bytes[] = "data_2 bytes";

class HomedirMethodsTest : public testing::Test {
 public:
  HomedirMethodsTest();
  virtual ~HomedirMethodsTest();

  // testing::Test:
  virtual void SetUp() override;
  virtual void TearDown() override;

  void RunProtobufMethodCallback(
      const chromeos::CryptohomeClient::ProtobufMethodCallback& callback);

  void StoreGetKeyDataExResult(
      bool success,
      MountError return_code,
      const std::vector<KeyDefinition>& key_definitions);

 protected:
  chromeos::MockCryptohomeClient* cryptohome_client_;

  // The reply that |cryptohome_client_| will make.
  cryptohome::BaseReply cryptohome_reply_;

  // The results of the most recent |HomedirMethods| method call.
  bool success_;
  MountError return_code_;
  std::vector<KeyDefinition> key_definitions_;

 private:
  DISALLOW_COPY_AND_ASSIGN(HomedirMethodsTest);
};

HomedirMethodsTest::HomedirMethodsTest() : cryptohome_client_(NULL),
                                           success_(false),
                                           return_code_(MOUNT_ERROR_FATAL) {
}

HomedirMethodsTest::~HomedirMethodsTest() {
}

void HomedirMethodsTest::SetUp() {
  scoped_ptr<chromeos::MockCryptohomeClient> cryptohome_client(
      new chromeos::MockCryptohomeClient);
  cryptohome_client_ = cryptohome_client.get();
  chromeos::DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient(
      cryptohome_client.PassAs<chromeos::CryptohomeClient>());
  HomedirMethods::Initialize();
}

void HomedirMethodsTest::TearDown() {
  HomedirMethods::Shutdown();
  chromeos::DBusThreadManager::Shutdown();
}

void HomedirMethodsTest::RunProtobufMethodCallback(
    const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) {
  callback.Run(chromeos::DBUS_METHOD_CALL_SUCCESS,
               true,
               cryptohome_reply_);
}

void HomedirMethodsTest::StoreGetKeyDataExResult(
    bool success,
    MountError return_code,
    const std::vector<KeyDefinition>& key_definitions) {
  success_ = success;
  return_code_ = return_code;
  key_definitions_ = key_definitions;
}

// Verifies that the result of a GetKeyDataEx() call is correctly parsed.
TEST_F(HomedirMethodsTest, GetKeyDataEx) {
  AccountIdentifier expected_id;
  expected_id.set_email(kUserID);
  const cryptohome::AuthorizationRequest expected_auth;
  cryptohome::GetKeyDataRequest expected_request;
      expected_request.mutable_key()->mutable_data()->set_label(kKeyLabel);

  EXPECT_CALL(*cryptohome_client_,
              GetKeyDataEx(EqualsProto(expected_id),
                           EqualsProto(expected_auth),
                           EqualsProto(expected_request),
                           _))
      .Times(1)
      .WillOnce(WithArg<3>(Invoke(
          this,
          &HomedirMethodsTest::RunProtobufMethodCallback)));

  // Set up the reply that |cryptohome_client_| will make.
  cryptohome::GetKeyDataReply* reply =
      cryptohome_reply_.MutableExtension(cryptohome::GetKeyDataReply::reply);
  KeyData* key_data = reply->add_key_data();
  key_data->set_type(KeyData::KEY_TYPE_PASSWORD);
  key_data->set_label(kKeyLabel);
  key_data->mutable_privileges()->set_update(false);
  key_data->set_revision(kKeyRevision);
  key_data->add_authorization_data()->set_type(
      KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
  KeyProviderData* data = key_data->mutable_provider_data();
  KeyProviderData::Entry* entry = data->add_entry();
  entry->set_name(kProviderData1Name);
  entry->set_number(kProviderData1Number);
  entry = data->add_entry();
  entry->set_name(kProviderData2Name);
  entry->set_bytes(kProviderData2Bytes);

  // Call GetKeyDataEx().
  HomedirMethods::GetInstance()->GetKeyDataEx(
    Identification(kUserID),
    kKeyLabel,
    base::Bind(&HomedirMethodsTest::StoreGetKeyDataExResult,
               base::Unretained(this)));

  // Verify that the call was successful and the result was correctly parsed.
  EXPECT_TRUE(success_);
  EXPECT_EQ(MOUNT_ERROR_NONE, return_code_);
  ASSERT_EQ(1u, key_definitions_.size());
  const KeyDefinition& key_definition = key_definitions_.front();
  EXPECT_EQ(KeyDefinition::TYPE_PASSWORD, key_definition.type);
  EXPECT_EQ(PRIV_MOUNT | PRIV_ADD | PRIV_REMOVE,
            key_definition.privileges);
  EXPECT_EQ(kKeyRevision, key_definition.revision);
  ASSERT_EQ(1u, key_definition.authorization_data.size());
  EXPECT_EQ(KeyDefinition::AuthorizationData::TYPE_HMACSHA256,
            key_definition.authorization_data.front().type);
  ASSERT_EQ(2u, key_definition.provider_data.size());
  const KeyDefinition::ProviderData* provider_data =
      &key_definition.provider_data[0];
  EXPECT_EQ(kProviderData1Name, provider_data->name);
  ASSERT_TRUE(provider_data->number);
  EXPECT_EQ(kProviderData1Number, *provider_data->number.get());
  EXPECT_FALSE(provider_data->bytes);
  provider_data = &key_definition.provider_data[1];
  EXPECT_EQ(kProviderData2Name, provider_data->name);
  EXPECT_FALSE(provider_data->number);
  ASSERT_TRUE(provider_data->bytes);
  EXPECT_EQ(kProviderData2Bytes, *provider_data->bytes.get());
}

}  // namespace cryptohome
