// Copyright (C) 2025, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Duplicati.Library.Interface;
using Duplicati.Library.Main.Database;
using Duplicati.Library.Main.Volumes;
using Duplicati.Library.Utility;
using IFileEntry = Duplicati.Library.Interface.IFileEntry;
#nullable enable
namespace Duplicati.Library.Main;
///
/// Interface for the backend manager
///
internal interface IBackendManager : IDisposable
{
///
/// Uploads a block volume to the backend, including an optional index volume
///
/// The block volume to upload
/// The index volume to upload, if any
/// The action to call when the index volume is finished
/// Whether to wait for the upload to complete
/// The action to call when the database should be updated
/// The cancellation token
/// An awaitable task
Task PutAsync(VolumeWriterBase blockVolume, IndexVolumeWriter? indexVolume, Func? indexVolumeFinished, bool waitForComplete, Func? onDbUpdate, CancellationToken cancelToken);
///
/// Uploads a file to the backend without encryption
///
/// The name of the file to upload to
/// The file to upload
/// The cancellation token
/// An awaitable task
Task PutVerificationFileAsync(string remotename, TempFile tempFile, CancellationToken cancelToken);
///
/// Waits for the backend queue to be empty
///
/// The cancellation token
/// An awaitable task
Task WaitForEmptyAsync(CancellationToken cancellationToken);
///
/// Waits for the backend queue to be empty and flushes any pending messages to the database
///
/// The database to write pending messages to
/// The cancellation token
/// An awaitable task
Task WaitForEmptyAsync(LocalDatabase database, CancellationToken cancellationToken);
///
/// Lists the files on the backend
///
/// The cancellation token
/// An enumerable of file entries
Task> ListAsync(CancellationToken cancelToken);
///
/// Decrypts the given file and returns the decrypted file
///
/// The file to decrypt
/// The name of the file. Used for detecting encryption algorithm if not specified in options or if it differs from the options
/// The Duplicati options
/// The decrypted file
TempFile DecryptFile(TempFile volume, string volume_name, Options options);
///
/// Deletes a file on the backend
///
/// The name of the file to delete
/// The size of the file to delete, or -1 if not known
/// Whether to wait for the delete to complete
/// The cancellation token
/// An awaitable task
Task DeleteAsync(string remotename, long size, bool waitForComplete, CancellationToken cancelToken);
///
/// Applies or updates an object lock on a remote volume.
///
/// The name of the file to lock
/// The UTC time the lock should be in effect until
/// The cancellation token
Task SetObjectLockUntilAsync(string remotename, DateTime lockUntilUtc, CancellationToken cancelToken);
///
/// Gets the object lock expiration time for a remote volume.
///
/// The name of the file to check
/// The cancellation token
/// The UTC time the lock expires, or null if no lock is set
Task GetObjectLockUntilAsync(string remotename, CancellationToken cancelToken);
///
/// Gets the quota information for the backend
///
/// The cancellation token
/// The quota information, or null if not available or disabled
Task GetQuotaInfoAsync(CancellationToken cancelToken);
///
/// Gets a file with the hash and size
///
/// The name of the file to get
/// The hash of the file to get, or null if not known
/// The size of the file to get, or -1 if not known
/// The cancellation token
/// The file, hash, and size
Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, CancellationToken cancelToken);
///
/// Gets a file from the backend
///
/// The name of the file to get
/// The hash of the file to get, or null if not known
/// The size of the file to get, or -1 if not known
/// The cancellation token
/// The downloaded file
Task GetAsync(string remotename, string hash, long size, CancellationToken cancelToken);
///
/// Gets a file from the backend without decrypting it
///
/// The name of the remote volume
/// The hash of the volume
/// The size of the volume
/// The cancellation token
/// The downloaded file
Task GetDirectAsync(string remotename, string hash, long size, CancellationToken cancelToken);
///
/// Performs a download of the files specified, with pre-fetch to overlap the download and processing
///
/// The volumes to download
/// The cancellation token
/// The downloaded files, hash, size, and name
IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(IEnumerable volumes, CancellationToken cancelToken);
///
/// Flushes the database messages to the database
///
/// The database to write to
/// The cancellation token
///
Task FlushPendingMessagesAsync(LocalDatabase database, CancellationToken cancellationToken);
///
/// Updates the throttle values for upload and download
///
/// The maximum upload speed in bytes per second
/// The maximum download speed in bytes per second
void UpdateThrottleValues(long maxUploadPrSecond, long maxDownloadPrSecond);
///
/// Indicates whether the backend supports object locking operations.
///
bool SupportsObjectLocking { get; }
}