// 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_POOL_IMPL_H_
#define CHAPS_OBJECT_POOL_IMPL_H_

#include "chaps/object_pool.h"

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/macros.h>
#include <base/synchronization/lock.h>
#include <base/synchronization/waitable_event.h>

#include "chaps/object_store.h"

namespace chaps {

class ChapsFactory;
class HandleGenerator;
class ObjectImporter;
class SlotPolicy;

// Key: Object handle.
// Value: Object shared pointer.
typedef std::map<int, std::shared_ptr<const Object>> HandleObjectMap;
typedef std::set<const Object*> ObjectSet;

class ObjectPoolImpl : public ObjectPool {
 public:
  // The 'factory', 'handle_generator' and 'slot_policy' pointers are not owned
  // by the object pool. They must remain valid for the entire life of the
  // ObjectPoolImpl instance. If the object pool is not persistent, 'store'
  // should be NULL. Otherwise, 'store' will be owned by (and later deleted by)
  // the object pool.
  // If 'slot_policy' is nullptr, it means that all objects are allowed.
  ObjectPoolImpl(ChapsFactory* factory,
                 HandleGenerator* handle_generator,
                 SlotPolicy* slot_policy,
                 ObjectStore* store,
                 ObjectImporter* importer);
  ObjectPoolImpl(const ObjectPoolImpl&) = delete;
  ObjectPoolImpl& operator=(const ObjectPoolImpl&) = delete;

  ~ObjectPoolImpl() override;
  virtual bool Init();
  bool GetInternalBlob(int blob_id, std::string* blob) override;
  bool SetInternalBlob(int blob_id, const std::string& blob) override;
  bool SetEncryptionKey(const brillo::SecureBlob& key) override;
  Result Insert(Object* object) override;
  Result Import(Object* object) override;
  Result Delete(const Object* object) override;
  Result DeleteAll() override;
  Result Find(const Object* search_template,
              std::vector<const Object*>* matching_objects) override;
  Result FindByHandle(int handle, const Object** object) override;
  Object* GetModifiableObject(const Object* object) override;
  Result Flush(const Object* object) override;
  bool IsPrivateLoaded() override;

 private:
  Result AddObject(Object* object, bool from_external_source);
  // An object matches a template when it holds values for all template
  // attributes and those values match the template values. This function
  // returns true if the given object matches the given template.
  bool Matches(const Object* object_template, const Object* object);
  bool Parse(const ObjectBlob& object_blob, Object* object);
  bool Serialize(const Object* object, ObjectBlob* serialized);
  bool LoadBlobs(const std::map<int, ObjectBlob>& object_blobs);
  bool LoadPublicObjects();
  bool LoadPrivateObjects();

  // Allows us to quickly check whether an object exists in the pool.
  ObjectSet objects_;
  HandleObjectMap handle_object_map_;
  ChapsFactory* factory_;
  HandleGenerator* handle_generator_;
  SlotPolicy* slot_policy_;
  std::unique_ptr<ObjectStore> store_;
  std::unique_ptr<ObjectImporter> importer_;
  bool is_private_loaded_;
  base::Lock lock_;
  bool finish_import_required_;
};

}  // namespace chaps

#endif  // CHAPS_OBJECT_POOL_IMPL_H_
