#ifndef COREFRAME_LINUX_NATIVE_FILES_H_
#define COREFRAME_LINUX_NATIVE_FILES_H_

#include <flutter_linux/flutter_linux.h>

#include <cstdint>
#include <optional>
#include <string>
#include <vector>

struct _CoreframeWebViewHostPlugin;
typedef struct _CoreframeWebViewHostPlugin CoreframeWebViewHostPlugin;

struct LinuxNativeFileSelection {
  std::string source_path;
  std::string name;
};

struct LinuxStagedNativeFile {
  std::string name;
  int64_t size;
  std::string staged_path;
  std::optional<int64_t> last_modified_milliseconds;
  std::optional<std::string> media_type;

  FlValue *ToChannelValue() const;
};

enum class LinuxNativeFileStagingFailure {
  kCapacityExceeded,
  kUnreadable,
};

struct LinuxNativeFileStagingResult {
  std::vector<LinuxStagedNativeFile> files;
  std::optional<LinuxNativeFileStagingFailure> failure;
};

// Copies picker selections into Coreframe's private cache directory. This type
// performs no UI work and is run entirely away from Flutter's platform thread.
class LinuxNativeFileStager {
public:
  static constexpr size_t kMaximumFiles = 32;
  static constexpr int64_t kMaximumFileBytes = 128LL * 1024 * 1024;
  static constexpr int64_t kMaximumTotalBytes = 256LL * 1024 * 1024;

  explicit LinuxNativeFileStager(
      std::string staging_directory, size_t maximum_files = kMaximumFiles,
      int64_t maximum_file_bytes = kMaximumFileBytes,
      int64_t maximum_total_bytes = kMaximumTotalBytes);

  LinuxNativeFileStagingResult
  Stage(const std::vector<LinuxNativeFileSelection> &selections) const;

  static void Remove(const std::vector<LinuxStagedNativeFile> &files);
  static void SweepStale(const std::string &staging_directory);

private:
  std::string staging_directory_;
  size_t maximum_files_;
  int64_t maximum_file_bytes_;
  int64_t maximum_total_bytes_;
};

void initialize_linux_native_files(CoreframeWebViewHostPlugin *plugin);
void dispose_linux_native_files(CoreframeWebViewHostPlugin *plugin);

#endif // COREFRAME_LINUX_NATIVE_FILES_H_
