// Copyright 2019 The Fuchsia 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 GARNET_BIN_SYSTEM_MONITOR_HARVESTER_DOCKYARD_PROXY_FAKE_H_
#define GARNET_BIN_SYSTEM_MONITOR_HARVESTER_DOCKYARD_PROXY_FAKE_H_

#include <map>
#include <string>

#include "dockyard_proxy.h"

namespace harvester {

class DockyardProxyFake : public DockyardProxy {
 public:
  DockyardProxyFake() = default;
  ~DockyardProxyFake() = default;

  // |DockyardProxy|.
  DockyardProxyStatus Init() override;

  // |DockyardProxy|.
  DockyardProxyStatus SendInspectJson(const std::string& stream_name,
                                      const std::string& json) override;

  // |DockyardProxy|.
  DockyardProxyStatus SendSample(const std::string& stream_name,
                                 uint64_t value) override;

  // |DockyardProxy|.
  DockyardProxyStatus SendSampleList(const SampleList list) override;

  // |DockyardProxy|.
  DockyardProxyStatus SendStringSampleList(
      const StringSampleList list) override;

  // Get the value (or string) for a given dockyard path. Used for testing.
  // Returns true if the value was sent at all; false if it wasn't sent.
  bool CheckValueSent(const std::string& dockyard_path,
                      dockyard::SampleValue* value) const;
  bool CheckStringSent(const std::string& dockyard_path,
                       std::string* string) const;

 private:
  std::map<std::string, dockyard::SampleValue> sent_values_;
  std::map<std::string, std::string> sent_strings_;
};

}  // namespace harvester

#endif  // GARNET_BIN_SYSTEM_MONITOR_HARVESTER_DOCKYARD_PROXY_FAKE_H_
