// Copyright (c) 2012 The Chromium OS 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 "chaps/object_pool_impl.h"

#include <map>
#include <string>
#include <vector>

#include <base/memory/scoped_ptr.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "chaps/chaps_factory_mock.h"
#include "chaps/handle_generator_mock.h"
#include "chaps/object_importer_mock.h"
#include "chaps/object_mock.h"
#include "chaps/object_store_mock.h"
#include "chaps/proto_bindings/attributes.pb.h"

using chromeos::SecureBlob;
using std::map;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SetArgumentPointee;

namespace chaps {

namespace {

Object* CreateObjectMock() {
  ObjectMock* o = new ObjectMock();
  o->SetupFake();
  EXPECT_CALL(*o, GetObjectClass()).Times(AnyNumber());
  EXPECT_CALL(*o, SetAttributes(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, FinalizeNewObject()).WillRepeatedly(Return(CKR_OK));
  EXPECT_CALL(*o, Copy(_)).WillRepeatedly(Return(CKR_OK));
  EXPECT_CALL(*o, IsTokenObject()).Times(AnyNumber());
  EXPECT_CALL(*o, IsPrivate()).Times(AnyNumber());
  EXPECT_CALL(*o, IsAttributePresent(_)).Times(AnyNumber());
  EXPECT_CALL(*o, GetAttributeString(_)).Times(AnyNumber());
  EXPECT_CALL(*o, GetAttributeInt(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, GetAttributeBool(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, SetAttributeString(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, SetAttributeInt(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, SetAttributeBool(_, _)).Times(AnyNumber());
  EXPECT_CALL(*o, GetAttributeMap()).Times(AnyNumber());
  EXPECT_CALL(*o, set_handle(_)).Times(AnyNumber());
  EXPECT_CALL(*o, set_store_id(_)).Times(AnyNumber());
  EXPECT_CALL(*o, handle()).Times(AnyNumber());
  EXPECT_CALL(*o, store_id()).Times(AnyNumber());
  return o;
}

int CreateHandle() {
  static int last_handle = 0;
  return ++last_handle;
}

}  // namespace

// A test fixture for object pools.
class TestObjectPool : public ::testing::Test {
 public:
  TestObjectPool() {
    // Setup the factory to return functional fake objects.
    EXPECT_CALL(factory_, CreateObject())
        .WillRepeatedly(Invoke(CreateObjectMock));
    EXPECT_CALL(handle_generator_, CreateHandle())
        .WillRepeatedly(Invoke(CreateHandle));
    // Create object pools to test with.
    store_ = new ObjectStoreMock();
    importer_ = new ObjectImporterMock();
    pool_.reset(
        new ObjectPoolImpl(&factory_, &handle_generator_, store_, importer_));
    pool2_.reset(new ObjectPoolImpl(&factory_, &handle_generator_, NULL, NULL));
  }

  ChapsFactoryMock factory_;
  ObjectStoreMock* store_;
  ObjectImporterMock* importer_;
  HandleGeneratorMock handle_generator_;
  scoped_ptr<ObjectPoolImpl> pool_;
  scoped_ptr<ObjectPoolImpl> pool2_;
};

// Test object pool initialization when using an object store.
TEST_F(TestObjectPool, Init) {
  // Create some fake persistent objects for the mock store to return.
  map<int, ObjectBlob> persistent_objects;
  AttributeList l;
  Attribute* a = l.add_attribute();
  a->set_type(CKA_ID);
  a->set_value("value");
  string s;
  l.SerializeToString(&s);
  persistent_objects[1].blob = s;
  persistent_objects[1].is_private = true;
  persistent_objects[2].blob = "not_valid_protobuf";
  persistent_objects[2].is_private = false;
  string tmp(32, 'A');
  SecureBlob key(tmp.begin(), tmp.end());
  EXPECT_CALL(*store_, GetInternalBlob(_, _)).WillRepeatedly(Return(false));
  EXPECT_CALL(*store_, SetInternalBlob(_, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(*store_, SetEncryptionKey(key))
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*store_, LoadPublicObjectBlobs(_))
      .WillOnce(Return(false))
      .WillRepeatedly(DoAll(SetArgumentPointee<0>(persistent_objects),
                            Return(true)));
  EXPECT_CALL(*store_, LoadPrivateObjectBlobs(_))
      .WillOnce(Return(false))
      .WillRepeatedly(DoAll(SetArgumentPointee<0>(persistent_objects),
                            Return(true)));
  EXPECT_CALL(*importer_, ImportObjects(pool_.get()))
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*importer_, FinishImportAsync(pool_.get()))
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  // Loading of public objects happens when the pool is initialized.
  EXPECT_TRUE(pool2_->Init());
  EXPECT_FALSE(pool_->Init());
  EXPECT_TRUE(pool_->Init());
  EXPECT_TRUE(pool_->Init());
  // Loading of private objects happens when the encryption key is set.
  EXPECT_TRUE(pool2_->SetEncryptionKey(key));
  EXPECT_FALSE(pool_->SetEncryptionKey(key));
  EXPECT_TRUE(pool_->SetEncryptionKey(key));
  EXPECT_TRUE(pool_->SetEncryptionKey(key));
  vector<const Object*> v;
  scoped_ptr<Object> find_all(CreateObjectMock());
  EXPECT_TRUE(pool_->Find(find_all.get(), &v));
  ASSERT_EQ(3, v.size());
  EXPECT_TRUE(v[0]->GetAttributeString(CKA_ID) == string("value"));
  EXPECT_TRUE(v[1]->GetAttributeString(CKA_ID) == string("value"));
  EXPECT_TRUE(v[2]->GetAttributeString(CKA_ID) == string("value"));
}

// Test the methods that should just pass through to the object store.
TEST_F(TestObjectPool, StorePassThrough) {
  string s("test");
  SecureBlob blob("test");
  EXPECT_CALL(*store_, GetInternalBlob(1, _))
      .WillOnce(Return(false))
      .WillOnce(Return(true));
  EXPECT_CALL(*store_, SetInternalBlob(1, s))
      .WillOnce(Return(false))
      .WillOnce(Return(true));
  EXPECT_CALL(*store_, LoadPublicObjectBlobs(_))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*store_, LoadPrivateObjectBlobs(_))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*store_, SetEncryptionKey(blob))
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  EXPECT_FALSE(pool2_->GetInternalBlob(1, &s));
  EXPECT_FALSE(pool2_->SetInternalBlob(1, s));
  EXPECT_TRUE(pool2_->SetEncryptionKey(blob));
  EXPECT_FALSE(pool_->GetInternalBlob(1, &s));
  EXPECT_TRUE(pool_->GetInternalBlob(1, &s));
  EXPECT_FALSE(pool_->SetInternalBlob(1, s));
  EXPECT_TRUE(pool_->SetInternalBlob(1, s));
  EXPECT_FALSE(pool_->SetEncryptionKey(blob));
  EXPECT_TRUE(pool_->SetEncryptionKey(blob));
}

// Test basic object management operations.
TEST_F(TestObjectPool, InsertFindUpdateDelete) {
  EXPECT_CALL(*store_, InsertObjectBlob(_, _))
      .WillOnce(Return(false))
      .WillRepeatedly(DoAll(SetArgumentPointee<1>(3), Return(true)));
  EXPECT_CALL(*store_, UpdateObjectBlob(3, _))
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*store_, DeleteObjectBlob(3))
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  vector<const Object*> v;
  scoped_ptr<Object> find_all(CreateObjectMock());
  EXPECT_TRUE(pool2_->Find(find_all.get(), &v));
  EXPECT_EQ(0, v.size());
  EXPECT_TRUE(pool2_->Insert(CreateObjectMock()));
  EXPECT_TRUE(pool2_->Insert(CreateObjectMock()));
  EXPECT_TRUE(pool2_->Find(find_all.get(), &v));
  ASSERT_EQ(2, v.size());
  Object* o = pool2_->GetModifiableObject(v[0]);
  EXPECT_TRUE(pool2_->Flush(o));
  EXPECT_TRUE(pool2_->Delete(v[0]));
  EXPECT_TRUE(pool2_->Delete(v[1]));
  v.clear();
  EXPECT_TRUE(pool2_->Find(find_all.get(), &v));
  EXPECT_EQ(0, v.size());
  // Now with the persistent pool.
  EXPECT_TRUE(pool_->Find(find_all.get(), &v));
  EXPECT_EQ(0, v.size());
  Object* tmp = CreateObjectMock();
  EXPECT_FALSE(pool_->Insert(tmp));
  EXPECT_TRUE(pool_->Insert(tmp));
  EXPECT_TRUE(pool_->Find(find_all.get(), &v));
  ASSERT_EQ(1, v.size());
  o = pool_->GetModifiableObject(v[0]);
  EXPECT_FALSE(pool_->Flush(o));
  EXPECT_TRUE(pool_->Flush(o));
  EXPECT_FALSE(pool_->Delete(v[0]));
  EXPECT_TRUE(pool_->Delete(v[0]));
  v.clear();
  EXPECT_TRUE(pool_->Find(find_all.get(), &v));
  EXPECT_EQ(0, v.size());
}

// Test handling of an invalid object pointer.
TEST_F(TestObjectPool, UnknownObject) {
  scoped_ptr<Object> o(CreateObjectMock());
  EXPECT_FALSE(pool_->Flush(o.get()));
  EXPECT_FALSE(pool_->Delete(o.get()));
  EXPECT_FALSE(pool2_->Flush(o.get()));
  EXPECT_FALSE(pool2_->Delete(o.get()));
}

// Test multiple insertion of the same object pointer.
TEST_F(TestObjectPool, DuplicateObject) {
  Object* o = CreateObjectMock();
  EXPECT_CALL(*store_, InsertObjectBlob(_, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<1>(3), Return(true)));
  EXPECT_TRUE(pool_->Insert(o));
  EXPECT_FALSE(pool_->Insert(o));
  Object* o2 = CreateObjectMock();
  EXPECT_TRUE(pool2_->Insert(o2));
  EXPECT_FALSE(pool2_->Insert(o2));
}

TEST_F(TestObjectPool, DeleteAll) {
  EXPECT_CALL(*store_, InsertObjectBlob(_, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<1>(3), Return(true)));
  EXPECT_CALL(*store_, DeleteAllObjectBlobs())
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  EXPECT_TRUE(pool_->Insert(CreateObjectMock()));
  EXPECT_TRUE(pool_->Insert(CreateObjectMock()));
  EXPECT_TRUE(pool_->Insert(CreateObjectMock()));
  vector<const Object*> v;
  scoped_ptr<Object> find_all(CreateObjectMock());
  EXPECT_TRUE(pool_->Find(find_all.get(), &v));
  EXPECT_EQ(3, v.size());
  // Test the store failure is passed back but cached objects are still deleted.
  EXPECT_FALSE(pool_->DeleteAll());
  v.clear();
  EXPECT_TRUE(pool_->Find(find_all.get(), &v));
  EXPECT_EQ(0, v.size());
  EXPECT_TRUE(pool_->Insert(CreateObjectMock()));
  EXPECT_TRUE(pool_->Insert(CreateObjectMock()));
  EXPECT_TRUE(pool_->Insert(CreateObjectMock()));
  // Test with store success.
  EXPECT_TRUE(pool_->DeleteAll());
  v.clear();
  EXPECT_TRUE(pool_->Find(find_all.get(), &v));
  EXPECT_EQ(0, v.size());
  // Test with session pool.
  EXPECT_CALL(*store_, InsertObjectBlob(_, _)).Times(0);
  EXPECT_CALL(*store_, DeleteAllObjectBlobs()).Times(0);
  EXPECT_TRUE(pool2_->Insert(CreateObjectMock()));
  EXPECT_TRUE(pool2_->Insert(CreateObjectMock()));
  EXPECT_TRUE(pool2_->Insert(CreateObjectMock()));
  v.clear();
  EXPECT_TRUE(pool2_->Find(find_all.get(), &v));
  EXPECT_EQ(3, v.size());
  EXPECT_TRUE(pool2_->DeleteAll());
  v.clear();
  EXPECT_TRUE(pool2_->Find(find_all.get(), &v));
  EXPECT_EQ(0, v.size());
}

}  // namespace chaps

int main(int argc, char** argv) {
  ::testing::InitGoogleMock(&argc, argv);
  return RUN_ALL_TESTS();
}
