// Copyright 2020 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_STORAGE_BLOBFS_COMPRESSION_EXTERNAL_DECOMPRESSOR_H_
#define SRC_STORAGE_BLOBFS_COMPRESSION_EXTERNAL_DECOMPRESSOR_H_

#include <fuchsia/blobfs/internal/cpp/fidl.h>
#include <fuchsia/blobfs/internal/llcpp/fidl.h>
#include <lib/zx/fifo.h>
#include <lib/zx/status.h>
#include <lib/zx/vmo.h>

#include "src/storage/blobfs/compression-settings.h"
#include "src/storage/blobfs/compression/seekable-decompressor.h"

namespace blobfs {

// A client class for managing the connection to the decompressor sandbox,
// sending messages, and returning the status result. This class is *not* thread
// safe.
class ExternalDecompressorClient {
 public:
  DISALLOW_COPY_ASSIGN_AND_MOVE(ExternalDecompressorClient);

  // Creates a DecompressorClient that takes data from `compressed_vmo` and
  // places the results in `decompressed_vmo`. This calls `Prepare()` and
  // returns a failure if it cannot succeed on the first try. Both vmos require
  // the ZX_DEFAULT_VMO_RIGHTS except that ZX_RIGHT_WRITE is not required on
  // `compressed_vmo`, this permission will be ommited before sending to the
  // external decompressor if present.
  static zx::status<std::unique_ptr<ExternalDecompressorClient>> Create(
      const zx::vmo& decompressed_vmo, const zx::vmo& compressed_vmo);

  // Sends the request over the fifo, and awaits the response before verifying
  // the resulting size and reporting the status passed from the server. This
  // succeeds only if the resulting decompressed size matches the
  // `decompressed.size`. Starts by calling `Prepare()`.
  zx_status_t SendMessage(const llcpp::fuchsia::blobfs::internal::DecompressRequest& request);

  // Convert from fidl compatible enum to local.
  static CompressionAlgorithm CompressionAlgorithmFidlToLocal(
      llcpp::fuchsia::blobfs::internal::CompressionAlgorithm algorithm);

  // Convert to fidl compatible enum from local.
  static llcpp::fuchsia::blobfs::internal::CompressionAlgorithm CompressionAlgorithmLocalToFidl(
      CompressionAlgorithm algorithm);

  // Convert to fidl compatible enum from local for partial decompresion.
  static zx::status<llcpp::fuchsia::blobfs::internal::CompressionAlgorithm>
  CompressionAlgorithmLocalToFidlForPartial(CompressionAlgorithm algorithm);

 private:
  ExternalDecompressorClient() = default;

  // If the fifo is useable nothing is done and returns ZX_OK. If the fifo is
  // not ready to use, this attempts to set one up via the DecompressorCreator.
  zx_status_t Prepare();

  // If the DecompressorCreator fidl channel is ready then nothing is done.
  // Otherwise the channel is set up.
  zx_status_t PrepareDecompressorCreator();

  // The vmo that will contain the decompressed data for requests. A copy is kept
  // so that if it needs to reconnect with the server another copy can be sent.
  zx::vmo decompressed_vmo_;

  // The vmo that will contain the compressed data for requests. A copy is kept
  // so that if it needs to reconnect with the server another copy can be sent.
  zx::vmo compressed_vmo_;

  // Fidl connection to the DecompressorCreator.
  fuchsia::blobfs::internal::DecompressorCreatorSyncPtr decompressor_creator_;

  // The fifo that communicates with the Decompressor.
  zx::fifo fifo_;
};

// A class for decompressing entire files for which there is an implementation
// of the Decompressor interface for the `algorithm`. Uses the given `client`
// for communication to the external decompressor process.
class ExternalDecompressor {
 public:
  ExternalDecompressor(ExternalDecompressorClient* client, CompressionAlgorithm algorithm);
  DISALLOW_COPY_ASSIGN_AND_MOVE(ExternalDecompressor);

  // Performs decompression for an entire archive using the provided client.
  zx_status_t Decompress(size_t uncompressed_size, size_t max_compressed_size);

 private:
  // Client used for communication with the decompressor.
  ExternalDecompressorClient* client_;

  // The algorithm to be used for this file.
  CompressionAlgorithm algorithm_;
};

// A class for decompressing parts of files for which there is an implementation
// of the SeekableDecompressor interface for the `algorithm`. Uses the given
// `client` for communication to the external decompressor process.
class ExternalSeekableDecompressor {
 public:
  ExternalSeekableDecompressor(ExternalDecompressorClient* client,
                               SeekableDecompressor* decompressor);
  DISALLOW_COPY_ASSIGN_AND_MOVE(ExternalSeekableDecompressor);

  // Decompresses one region by sending a request to the provided client.
  // The range specified must be one or more entire completeable chunks.
  // `compressed_offset` is the offset into the `compressed_vmo_` to start
  // decompressing from.
  zx_status_t DecompressRange(size_t compressed_offset, size_t compressed_size,
                              size_t uncompressed_size);

 private:
  // Client used for communication with the decompressor.
  ExternalDecompressorClient* client_;

  // The SeekableDecompressor that would otherwise be used to decompress
  // locally, which has the CompressionMapping information.
  SeekableDecompressor* decompressor_;
};

}  // namespace blobfs

#endif  // SRC_STORAGE_BLOBFS_COMPRESSION_EXTERNAL_DECOMPRESSOR_H_
