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