// 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.

#ifndef CHAPS_OBJECT_STORE_IMPL_H_
#define CHAPS_OBJECT_STORE_IMPL_H_

#include "chaps/object_store.h"

#include <map>
#include <string>

#include <base/files/file_path.h>
#include <base/macros.h>
#include <base/memory/scoped_ptr.h>
#include <chromeos/secure_blob.h>
#include <gtest/gtest.h>
#include <leveldb/db.h>
#include <leveldb/env.h>

namespace chaps {

// An ObjectStore implementation based on SQLite.
class ObjectStoreImpl : public ObjectStore {
 public:
  ObjectStoreImpl();
  virtual ~ObjectStoreImpl();

  // Initializes the object store with the given database path. The magic file
  // name ":memory:" will cause the store to create a memory-only database which
  // is suitable for testing.
  bool Init(const base::FilePath& database_path);

  // ObjectStore methods.
  virtual bool GetInternalBlob(int blob_id, std::string* blob);
  virtual bool SetInternalBlob(int blob_id, const std::string& blob);
  virtual bool SetEncryptionKey(const chromeos::SecureBlob& key);
  virtual bool InsertObjectBlob(const ObjectBlob& blob, int* handle);
  virtual bool DeleteObjectBlob(int handle);
  virtual bool DeleteAllObjectBlobs();
  virtual bool UpdateObjectBlob(int handle, const ObjectBlob& blob);
  virtual bool LoadPublicObjectBlobs(std::map<int, ObjectBlob>* blobs);
  virtual bool LoadPrivateObjectBlobs(std::map<int, ObjectBlob>* blobs);

 private:
  enum BlobType {
    kInternal,
    kPrivate,
    kPublic
  };

  // Loads all object of a given type.
  bool LoadObjectBlobs(BlobType type, std::map<int, ObjectBlob>* blobs);

  // Encrypts an object blob with a random IV and appends an HMAC.
  bool Encrypt(const ObjectBlob& plain_text,
               ObjectBlob* cipher_text);

  // Verifies and decrypts an object blob.
  bool Decrypt(const ObjectBlob& cipher_text,
               ObjectBlob* plain_text);

  // Computes an HMAC and appends it to the given input.
  std::string AppendHMAC(const std::string& input,
                         const chromeos::SecureBlob& key);

  // Verifies an appended HMAC and strips it from the given input.
  bool VerifyAndStripHMAC(const std::string& input,
                          const chromeos::SecureBlob& key,
                          std::string* stripped);

  // Creates and returns a unique database key for a blob.
  std::string CreateBlobKey(BlobType type, int blob_id);

  // Given a valid blob key (as created by CreateBlobKey), determines whether
  // the blob is internal, public, or private and the blob id. Returns true on
  // success.
  bool ParseBlobKey(const std::string& key, BlobType* type, int* blob_id);

  // Computes and returns the next (unused) blob id;
  bool GetNextID(int* next_id);

  // Reads a blob from the database. Returns true on success.
  bool ReadBlob(const std::string& key, std::string* value);

  // Reads an integer from the database. Returns true on success.
  bool ReadInt(const std::string& key, int* value);

  // Writes a blob to the database. Returns true on success.
  bool WriteBlob(const std::string& key, const std::string& value);

  // Writes an integer to the database. Returns true on success.
  bool WriteInt(const std::string& key, int value);

  // Returns the blob type for the specified blob. If 'blob_id' is unknown,
  // kInternal is returned.
  BlobType GetBlobType(int blob_id);

  // These strings are used to construct database keys for blobs. In general the
  // format of a blob database key is: <prefix><separator><id>.
  static const char kInternalBlobKeyPrefix[];
  static const char kPublicBlobKeyPrefix[];
  static const char kPrivateBlobKeyPrefix[];
  static const char kBlobKeySeparator[];
  // The key for the database version. The existence of this value indicates the
  // database is not new.
  static const char kDatabaseVersionKey[];
  // The database key for the ID tracker, which always holds a value larger than
  // any object blob ID in use.
  static const char kIDTrackerKey[];
  static const int kAESKeySizeBytes;
  static const int kHMACSizeBytes;
  // The leveldb directory.
  static const char kDatabaseDirectory[];
  // A directory in which to backup a corrupted database before recreating.
  static const char kCorruptDatabaseDirectory[];
  // An obfuscation key used for public objects.
  static const char kObfuscationKey[];
  // The current blob format version.
  static const int kBlobVersion;

  chromeos::SecureBlob key_;
  scoped_ptr<leveldb::Env> env_;
  scoped_ptr<leveldb::DB> db_;
  std::map<int, BlobType> blob_type_map_;

  friend class TestObjectStoreEncryption;
  FRIEND_TEST(TestObjectStoreEncryption, EncryptionInit);
  FRIEND_TEST(TestObjectStoreEncryption, Encryption);
  FRIEND_TEST(TestObjectStoreEncryption, CBCMode);

  DISALLOW_COPY_AND_ASSIGN(ObjectStoreImpl);
};

}  // namespace chaps

#endif  // CHAPS_OBJECT_STORE_IMPL_H_
