// Copyright 2018 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.
//
// WARNING: This file is machine generated by fidlmerge.

#ifndef SRC_LEDGER_BIN_FIDL_SYNCABLE_PUBLIC_H_
#define SRC_LEDGER_BIN_FIDL_SYNCABLE_PUBLIC_H_

#include <fuchsia/ledger/cpp/fidl.h>
#include <lib/fidl/cpp/interface_request.h>

#include "src/ledger/bin/fidl/syncable/syncable_binding.h"
#include "src/ledger/bin/public/status.h"

namespace fuchsia {
namespace ledger {

class LedgerSyncableDelegate {
 public:
  using FidlInterface = Ledger;
  class Impl;

  virtual ~LedgerSyncableDelegate() = default;
  virtual void GetPage(::std::unique_ptr<::fuchsia::ledger::PageId> id,
                       ::fidl::InterfaceRequest<::fuchsia::ledger::Page> page_request,
                       ::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void GetRootPage(::fidl::InterfaceRequest<::fuchsia::ledger::Page> page_request,
                           ::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void SetConflictResolverFactory(
      ::fidl::InterfaceHandle<::fuchsia::ledger::ConflictResolverFactory> factory,
      ::fit::function<void(::ledger::Status)> callback) = 0;
};

class LedgerSyncableDelegate::Impl : public Ledger {
 public:
  static constexpr char kInterfaceName[] = "Ledger";
  Impl(LedgerSyncableDelegate* delegate, ::ledger::SyncableBinding<LedgerSyncableDelegate>* binding)
      : delegate_(delegate), binding_(binding) {}

 private:
  void GetPage(::std::unique_ptr<::fuchsia::ledger::PageId> id,
               ::fidl::InterfaceRequest<::fuchsia::ledger::Page> page_request) override {
    delegate_->GetPage(::std::move(id), ::std::move(page_request),
                       binding_->NewErrorCallback("GetPage"));
  }
  void GetRootPage(::fidl::InterfaceRequest<::fuchsia::ledger::Page> page_request) override {
    delegate_->GetRootPage(::std::move(page_request), binding_->NewErrorCallback("GetRootPage"));
  }
  void SetConflictResolverFactory(
      ::fidl::InterfaceHandle<::fuchsia::ledger::ConflictResolverFactory> factory) override {
    delegate_->SetConflictResolverFactory(::std::move(factory),
                                          binding_->NewErrorCallback("SetConflictResolverFactory"));
  }
  void Sync(::fit::function<void()> callback) override { binding_->Sync(::std::move(callback)); }

  LedgerSyncableDelegate* delegate_;
  ::ledger::SyncableBinding<LedgerSyncableDelegate>* binding_;
};

class PageSyncableDelegate {
 public:
  using FidlInterface = Page;
  class Impl;

  virtual ~PageSyncableDelegate() = default;
  virtual void GetId(
      ::fit::function<void(::ledger::Status, ::fuchsia::ledger::PageId)> callback) = 0;
  virtual void GetSnapshot(
      ::fidl::InterfaceRequest<::fuchsia::ledger::PageSnapshot> snapshot_request,
      ::std::vector<uint8_t> key_prefix,
      ::fidl::InterfaceHandle<::fuchsia::ledger::PageWatcher> watcher,
      ::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void Put(::std::vector<uint8_t> key, ::std::vector<uint8_t> value,
                   ::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void PutWithPriority(::std::vector<uint8_t> key, ::std::vector<uint8_t> value,
                               ::fuchsia::ledger::Priority priority,
                               ::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void PutReference(::std::vector<uint8_t> key, ::fuchsia::ledger::Reference reference,
                            ::fuchsia::ledger::Priority priority,
                            ::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void Delete(::std::vector<uint8_t> key,
                      ::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void Clear(::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void CreateReferenceFromSocket(
      uint64_t size, ::zx::socket data,
      ::fit::function<void(::ledger::Status,
                           ::fuchsia::ledger::Page_CreateReferenceFromSocket_Result)>
          callback) = 0;
  virtual void CreateReferenceFromBuffer(
      ::fuchsia::mem::Buffer buffer,
      ::fit::function<void(::ledger::Status,
                           ::fuchsia::ledger::Page_CreateReferenceFromBuffer_Result)>
          callback) = 0;
  virtual void StartTransaction(::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void Commit(::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void Rollback(::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void SetSyncStateWatcher(::fidl::InterfaceHandle<::fuchsia::ledger::SyncWatcher> watcher,
                                   ::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void WaitForConflictResolution(
      ::fit::function<void(::ledger::Status, ::fuchsia::ledger::ConflictResolutionWaitStatus)>
          callback) = 0;
};

class PageSyncableDelegate::Impl : public Page {
 public:
  static constexpr char kInterfaceName[] = "Page";
  Impl(PageSyncableDelegate* delegate, ::ledger::SyncableBinding<PageSyncableDelegate>* binding)
      : delegate_(delegate), binding_(binding) {}

 private:
  void GetId(::fit::function<void(::fuchsia::ledger::PageId)> callback) override {
    delegate_->GetId(binding_->WrapOperation("GetId", ::std::move(callback)));
  }
  void GetSnapshot(::fidl::InterfaceRequest<::fuchsia::ledger::PageSnapshot> snapshot_request,
                   ::std::vector<uint8_t> key_prefix,
                   ::fidl::InterfaceHandle<::fuchsia::ledger::PageWatcher> watcher) override {
    delegate_->GetSnapshot(::std::move(snapshot_request), ::std::move(key_prefix),
                           ::std::move(watcher), binding_->NewErrorCallback("GetSnapshot"));
  }
  void Put(::std::vector<uint8_t> key, ::std::vector<uint8_t> value) override {
    delegate_->Put(::std::move(key), ::std::move(value), binding_->NewErrorCallback("Put"));
  }
  void PutWithPriority(::std::vector<uint8_t> key, ::std::vector<uint8_t> value,
                       ::fuchsia::ledger::Priority priority) override {
    delegate_->PutWithPriority(::std::move(key), ::std::move(value), ::std::move(priority),
                               binding_->NewErrorCallback("PutWithPriority"));
  }
  void PutReference(::std::vector<uint8_t> key, ::fuchsia::ledger::Reference reference,
                    ::fuchsia::ledger::Priority priority) override {
    delegate_->PutReference(::std::move(key), ::std::move(reference), ::std::move(priority),
                            binding_->NewErrorCallback("PutReference"));
  }
  void Delete(::std::vector<uint8_t> key) override {
    delegate_->Delete(::std::move(key), binding_->NewErrorCallback("Delete"));
  }
  void Clear() override { delegate_->Clear(binding_->NewErrorCallback("Clear")); }
  void CreateReferenceFromSocket(
      uint64_t size, ::zx::socket data,
      ::fit::function<void(::fuchsia::ledger::Page_CreateReferenceFromSocket_Result)> callback)
      override {
    delegate_->CreateReferenceFromSocket(
        ::std::move(size), ::std::move(data),
        binding_->WrapOperation("CreateReferenceFromSocket", ::std::move(callback)));
  }
  void CreateReferenceFromBuffer(
      ::fuchsia::mem::Buffer buffer,
      ::fit::function<void(::fuchsia::ledger::Page_CreateReferenceFromBuffer_Result)> callback)
      override {
    delegate_->CreateReferenceFromBuffer(
        ::std::move(buffer),
        binding_->WrapOperation("CreateReferenceFromBuffer", ::std::move(callback)));
  }
  void StartTransaction() override {
    delegate_->StartTransaction(binding_->NewErrorCallback("StartTransaction"));
  }
  void Commit() override { delegate_->Commit(binding_->NewErrorCallback("Commit")); }
  void Rollback() override { delegate_->Rollback(binding_->NewErrorCallback("Rollback")); }
  void SetSyncStateWatcher(
      ::fidl::InterfaceHandle<::fuchsia::ledger::SyncWatcher> watcher) override {
    delegate_->SetSyncStateWatcher(::std::move(watcher),
                                   binding_->NewErrorCallback("SetSyncStateWatcher"));
  }
  void WaitForConflictResolution(
      ::fit::function<void(::fuchsia::ledger::ConflictResolutionWaitStatus)> callback) override {
    delegate_->WaitForConflictResolution(
        binding_->WrapOperation("WaitForConflictResolution", ::std::move(callback)));
  }
  void Sync(::fit::function<void()> callback) override { binding_->Sync(::std::move(callback)); }

  PageSyncableDelegate* delegate_;
  ::ledger::SyncableBinding<PageSyncableDelegate>* binding_;
};

class PageSnapshotSyncableDelegate {
 public:
  using FidlInterface = PageSnapshot;
  class Impl;

  virtual ~PageSnapshotSyncableDelegate() = default;
  virtual void GetEntries(
      ::std::vector<uint8_t> key_start, ::std::unique_ptr<::fuchsia::ledger::Token> token,
      ::fit::function<void(::ledger::Status, ::std::vector<::fuchsia::ledger::Entry>,
                           ::std::unique_ptr<::fuchsia::ledger::Token>)>
          callback) = 0;
  virtual void GetEntriesInline(
      ::std::vector<uint8_t> key_start, ::std::unique_ptr<::fuchsia::ledger::Token> token,
      ::fit::function<void(::ledger::Status, ::std::vector<::fuchsia::ledger::InlinedEntry>,
                           ::std::unique_ptr<::fuchsia::ledger::Token>)>
          callback) = 0;
  virtual void GetKeys(::std::vector<uint8_t> key_start,
                       ::std::unique_ptr<::fuchsia::ledger::Token> token,
                       ::fit::function<void(::ledger::Status, ::std::vector<::std::vector<uint8_t>>,
                                            ::std::unique_ptr<::fuchsia::ledger::Token>)>
                           callback) = 0;
  virtual void Get(
      ::std::vector<uint8_t> key,
      ::fit::function<void(::ledger::Status, ::fuchsia::ledger::PageSnapshot_Get_Result)>
          callback) = 0;
  virtual void GetInline(
      ::std::vector<uint8_t> key,
      ::fit::function<void(::ledger::Status, ::fuchsia::ledger::PageSnapshot_GetInline_Result)>
          callback) = 0;
  virtual void Fetch(
      ::std::vector<uint8_t> key,
      ::fit::function<void(::ledger::Status, ::fuchsia::ledger::PageSnapshot_Fetch_Result)>
          callback) = 0;
  virtual void FetchPartial(
      ::std::vector<uint8_t> key, int64_t offset, int64_t max_size,
      ::fit::function<void(::ledger::Status, ::fuchsia::ledger::PageSnapshot_FetchPartial_Result)>
          callback) = 0;
};

class PageSnapshotSyncableDelegate::Impl : public PageSnapshot {
 public:
  static constexpr char kInterfaceName[] = "PageSnapshot";
  Impl(PageSnapshotSyncableDelegate* delegate,
       ::ledger::SyncableBinding<PageSnapshotSyncableDelegate>* binding)
      : delegate_(delegate), binding_(binding) {}

 private:
  void GetEntries(::std::vector<uint8_t> key_start,
                  ::std::unique_ptr<::fuchsia::ledger::Token> token,
                  ::fit::function<void(::std::vector<::fuchsia::ledger::Entry>,
                                       ::std::unique_ptr<::fuchsia::ledger::Token>)>
                      callback) override {
    delegate_->GetEntries(::std::move(key_start), ::std::move(token),
                          binding_->WrapOperation("GetEntries", ::std::move(callback)));
  }
  void GetEntriesInline(::std::vector<uint8_t> key_start,
                        ::std::unique_ptr<::fuchsia::ledger::Token> token,
                        ::fit::function<void(::std::vector<::fuchsia::ledger::InlinedEntry>,
                                             ::std::unique_ptr<::fuchsia::ledger::Token>)>
                            callback) override {
    delegate_->GetEntriesInline(::std::move(key_start), ::std::move(token),
                                binding_->WrapOperation("GetEntriesInline", ::std::move(callback)));
  }
  void GetKeys(::std::vector<uint8_t> key_start, ::std::unique_ptr<::fuchsia::ledger::Token> token,
               ::fit::function<void(::std::vector<::std::vector<uint8_t>>,
                                    ::std::unique_ptr<::fuchsia::ledger::Token>)>
                   callback) override {
    delegate_->GetKeys(::std::move(key_start), ::std::move(token),
                       binding_->WrapOperation("GetKeys", ::std::move(callback)));
  }
  void Get(::std::vector<uint8_t> key,
           ::fit::function<void(::fuchsia::ledger::PageSnapshot_Get_Result)> callback) override {
    delegate_->Get(::std::move(key), binding_->WrapOperation("Get", ::std::move(callback)));
  }
  void GetInline(
      ::std::vector<uint8_t> key,
      ::fit::function<void(::fuchsia::ledger::PageSnapshot_GetInline_Result)> callback) override {
    delegate_->GetInline(::std::move(key),
                         binding_->WrapOperation("GetInline", ::std::move(callback)));
  }
  void Fetch(
      ::std::vector<uint8_t> key,
      ::fit::function<void(::fuchsia::ledger::PageSnapshot_Fetch_Result)> callback) override {
    delegate_->Fetch(::std::move(key), binding_->WrapOperation("Fetch", ::std::move(callback)));
  }
  void FetchPartial(::std::vector<uint8_t> key, int64_t offset, int64_t max_size,
                    ::fit::function<void(::fuchsia::ledger::PageSnapshot_FetchPartial_Result)>
                        callback) override {
    delegate_->FetchPartial(::std::move(key), ::std::move(offset), ::std::move(max_size),
                            binding_->WrapOperation("FetchPartial", ::std::move(callback)));
  }
  void Sync(::fit::function<void()> callback) override { binding_->Sync(::std::move(callback)); }

  PageSnapshotSyncableDelegate* delegate_;
  ::ledger::SyncableBinding<PageSnapshotSyncableDelegate>* binding_;
};

class MergeResultProviderSyncableDelegate {
 public:
  using FidlInterface = MergeResultProvider;
  class Impl;

  virtual ~MergeResultProviderSyncableDelegate() = default;
  virtual void GetFullDiff(
      ::std::unique_ptr<::fuchsia::ledger::Token> token,
      ::fit::function<void(::ledger::Status, ::std::vector<::fuchsia::ledger::DiffEntry>,
                           ::std::unique_ptr<::fuchsia::ledger::Token>)>
          callback) = 0;
  virtual void GetConflictingDiff(
      ::std::unique_ptr<::fuchsia::ledger::Token> token,
      ::fit::function<void(::ledger::Status, ::std::vector<::fuchsia::ledger::DiffEntry>,
                           ::std::unique_ptr<::fuchsia::ledger::Token>)>
          callback) = 0;
  virtual void Merge(::std::vector<::fuchsia::ledger::MergedValue> merge_changes,
                     ::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void MergeNonConflictingEntries(::fit::function<void(::ledger::Status)> callback) = 0;
  virtual void Done(::fit::function<void(::ledger::Status)> callback) = 0;
};

class MergeResultProviderSyncableDelegate::Impl : public MergeResultProvider {
 public:
  static constexpr char kInterfaceName[] = "MergeResultProvider";
  Impl(MergeResultProviderSyncableDelegate* delegate,
       ::ledger::SyncableBinding<MergeResultProviderSyncableDelegate>* binding)
      : delegate_(delegate), binding_(binding) {}

 private:
  void GetFullDiff(::std::unique_ptr<::fuchsia::ledger::Token> token,
                   ::fit::function<void(::std::vector<::fuchsia::ledger::DiffEntry>,
                                        ::std::unique_ptr<::fuchsia::ledger::Token>)>
                       callback) override {
    delegate_->GetFullDiff(::std::move(token),
                           binding_->WrapOperation("GetFullDiff", ::std::move(callback)));
  }
  void GetConflictingDiff(::std::unique_ptr<::fuchsia::ledger::Token> token,
                          ::fit::function<void(::std::vector<::fuchsia::ledger::DiffEntry>,
                                               ::std::unique_ptr<::fuchsia::ledger::Token>)>
                              callback) override {
    delegate_->GetConflictingDiff(
        ::std::move(token), binding_->WrapOperation("GetConflictingDiff", ::std::move(callback)));
  }
  void Merge(::std::vector<::fuchsia::ledger::MergedValue> merge_changes) override {
    delegate_->Merge(::std::move(merge_changes), binding_->NewErrorCallback("Merge"));
  }
  void MergeNonConflictingEntries() override {
    delegate_->MergeNonConflictingEntries(binding_->NewErrorCallback("MergeNonConflictingEntries"));
  }
  void Done() override { delegate_->Done(binding_->NewErrorCallback("Done")); }
  void Sync(::fit::function<void()> callback) override { binding_->Sync(::std::move(callback)); }

  MergeResultProviderSyncableDelegate* delegate_;
  ::ledger::SyncableBinding<MergeResultProviderSyncableDelegate>* binding_;
};

}  // namespace ledger
}  // namespace fuchsia

#endif  // SRC_LEDGER_BIN_FIDL_SYNCABLE_PUBLIC_H_
