// Copyright (c) 2014 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 SHILL_STUB_STORAGE_H_
#define SHILL_STUB_STORAGE_H_

#include <set>
#include <string>
#include <vector>

#include "shill/store_interface.h"

namespace shill {

// A stub implementation of StoreInterface.
class StubStorage : public StoreInterface {
 public:
  ~StubStorage() override {}

  bool Flush() override { return false; }
  std::set<std::string> GetGroups() const override { return {}; }
  std::set<std::string> GetGroupsWithKey(
      const std::string &key) const override {
    return {};
  }
  std::set<std::string> GetGroupsWithProperties(
      const KeyValueStore &properties) const override {
    return {};
  }
  bool ContainsGroup(const std::string &group) const override {
    return false;
  }
  bool DeleteKey(const std::string &group, const std::string &key)
      override { return false; }
  bool DeleteGroup(const std::string &group) override { return false; }
  bool SetHeader(const std::string &header) override { return false; }
  bool GetString(const std::string &group,
                 const std::string &key,
                 std::string *value) const override {
    return false;
  }
  bool SetString(const std::string &group,
                 const std::string &key,
                 const std::string &value) override {
    return false;
  }
  bool GetBool(const std::string &group,
               const std::string &key,
               bool *value) const override {
    return false;
  }
  bool SetBool(const std::string &group,
               const std::string &key,
               bool value) override {
    return false;
  }
  bool GetInt(const std::string &group,
              const std::string &key,
              int *value) const override {
    return false;
  }
  bool SetInt(const std::string &group,
              const std::string &key,
              int value) override {
    return false;
  }
  bool GetUint64(const std::string &group,
                 const std::string &key,
                 uint64_t *value) const override {
    return false;
  }
  bool SetUint64(const std::string &group,
                 const std::string &key,
                 uint64_t value) override {
    return false;
  }
  bool GetStringList(const std::string &group,
                     const std::string &key,
                     std::vector<std::string> *value) const override {
    return false;
  }
  bool SetStringList(const std::string &group,
                     const std::string &key,
                     const std::vector<std::string> &value) override {
    return false;
  }
  bool GetCryptedString(const std::string &group,
                        const std::string &key,
                        std::string *value) override {
    return false;
  }
  bool SetCryptedString(const std::string &group,
                        const std::string &key,
                        const std::string &value) override {
    return false;
  }
};

}  // namespace shill

#endif  // SHILL_STUB_STORAGE_H_
