// Copyright 2016 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 SRC_LEDGER_BIN_CLOUD_SYNC_IMPL_BATCH_UPLOAD_H_
#define SRC_LEDGER_BIN_CLOUD_SYNC_IMPL_BATCH_UPLOAD_H_

#include <fuchsia/ledger/cloud/cpp/fidl.h>
#include <lib/fit/function.h>

#include <functional>
#include <memory>
#include <vector>

#include "src/ledger/bin/encryption/public/encryption_service.h"
#include "src/ledger/bin/fidl/include/types.h"
#include "src/ledger/bin/storage/public/commit.h"
#include "src/ledger/bin/storage/public/page_storage.h"
#include "src/ledger/lib/coroutine/coroutine.h"
#include "src/ledger/lib/coroutine/coroutine_manager.h"
#include "src/ledger/lib/memory/weak_ptr.h"

namespace cloud_sync {

// Uploads a batch of commits along with unsynced storage objects and marks
// the uploaded artifacts as synced.
//
// Contract: The class doesn't reason about objects referenced by each commit,
// and instead uploads each unsynced object present in storage at the moment of
// calling Start(). Unsynced objects are marked as synced as they are uploaded.
// The commits in the batch are uploaded in one network request once all objects
// are uploaded.
//
// Usage: call Start() to kick off the upload. |on_done| is called after the
// upload is successfully completed. |on_error| will be called at most once
// after each error. Each time after |on_error| is called the client can
// call Retry() once to retry the upload.
// TODO(ppi): rather than DCHECK on storage errors, take separate callbacks for
// network and disk errors and let PageSync decide on how to handle each.
//
// Lifetime: if BatchUpload is deleted between Start() and |on_done| being
// called, it has to be deleted along with |storage| and |cloud_provider|, which
// otherwise can retain callbacks for pending uploads. This isn't a problem as
// long as the lifetime of page storage and page sync is managed together.
class BatchUpload {
 public:
  // In case of error in BatchUpload, ErrorType defines whether the error that
  // occurred is temporary (from cloud or auth provider), or permanent (from
  // storage or from encryption).
  enum class ErrorType {
    PERMANENT,
    TEMPORARY,
  };

  BatchUpload(coroutine::CoroutineService* coroutine_service, storage::PageStorage* storage,
              encryption::EncryptionService* encryption_service,
              cloud_provider::PageCloudPtr* page_cloud,
              std::vector<std::unique_ptr<const storage::Commit>> commits, fit::closure on_done,
              fit::function<void(ErrorType)> on_error, unsigned int max_concurrent_uploads = 10);
  BatchUpload(const BatchUpload&) = delete;
  BatchUpload& operator=(const BatchUpload&) = delete;
  ~BatchUpload();

  // Starts a new upload attempt. Results are reported through |on_done|
  // and |on_error| passed in the constructor. Can be called only once.
  void Start();

  // Retries the attempt to upload the commit batch. Each time |on_error| is called with a temporary
  // error, the client can retry by calling this method.
  void Retry();

 private:
  // Status of an upload operation: successful, or the type of the error to return.
  // This is ordered from best status to worst status.
  enum class UploadStatus {
    OK,
    TEMPORARY_ERROR,
    PERMANENT_ERROR,
  };

  // Converts an encryption status to an upload status.
  static UploadStatus EncryptionStatusToUploadStatus(encryption::Status status);

  // Converts a ledger status to an upload status.
  static UploadStatus LedgerStatusToUploadStatus(ledger::Status status);

  // Converts a cloud provider status to an upload status.
  static UploadStatus CloudStatusToUploadStatus(cloud_provider::Status status);

  // Converts a non-OK upload status to its error type.
  static ErrorType UploadStatusToErrorType(UploadStatus status);

  // Sets the upload status to |status| if it is worse than the current status.
  void SetUploadStatus(UploadStatus status);

  // Calls |on_error_| with the current error status.
  void SignalError();

  void StartObjectUpload();

  // Reads, encrypts and uploads one object. Errors are signaled in |status_|. The caller is
  // responsible for calling the |on_error_| callback when appropriate.
  void SynchronousUploadObject(coroutine::CoroutineHandler* handler,
                               storage::ObjectIdentifier identifier);

  // Filters already synced commits.
  void FilterAndUploadCommits();

  // Uploads the commits.
  void UploadCommits();

  // Re-enqueue the object for another upload attempt.
  void EnqueueForRetry(storage::ObjectIdentifier object_identifier);

  // Encodes a commit for sending to the cloud.
  void EncodeCommit(const storage::Commit& commit,
                    fit::function<void(UploadStatus, cloud_provider::Commit)> callback);

  // Encodes a diff for sending to the cloud.
  void EncodeDiff(storage::CommitIdView commit_id, std::vector<storage::EntryChange> entries,
                  fit::function<void(UploadStatus, cloud_provider::Diff)> callback);

  // Encodes a diff entry for sending to the cloud.
  void EncodeEntry(storage::EntryChange entry,
                   fit::function<void(UploadStatus, cloud_provider::DiffEntry)> callback);

  storage::PageStorage* const storage_;
  encryption::EncryptionService* const encryption_service_;
  cloud_provider::PageCloudPtr* const page_cloud_;
  std::vector<std::unique_ptr<const storage::Commit>> commits_;
  fit::closure on_done_;
  fit::function<void(ErrorType)> on_error_;

  // All remaining object ids to be uploaded along with this batch of commits.
  std::vector<storage::ObjectIdentifier> remaining_object_identifiers_;

  bool started_ = false;

  // Stores the status of the upload. If multiple errors have been encountered, stores the worst
  // error (permanent if any permanent error has been encountered, temporary otherwise).
  //
  // Transitions: this always goes from best to worst (OK -> TEMPORARY_ERROR -> PERMANENT_ERROR),
  // except in |Retry| where the status can transition from |TEMPORARY_ERROR| to |OK|.
  UploadStatus status_ = UploadStatus::OK;

  coroutine::CoroutineManager coroutine_manager_;

  // Must be the last member.
  ledger::WeakPtrFactory<BatchUpload> weak_ptr_factory_;
};

}  // namespace cloud_sync

#endif  // SRC_LEDGER_BIN_CLOUD_SYNC_IMPL_BATCH_UPLOAD_H_
