/**
 * Custom utility type to make properties required, but still allow null if defined.
 * @internal
 */
export type DeepRequired<T> = {
  [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
};

export enum CloudStorageScope {
  Documents = 'documents',
  AppData = 'app_data',
}

/**
 * Controls which on-device directory `CloudStorageScope.Documents` maps to on iCloud.
 * @provider icloud
 */
export type ICloudDocumentsMode = 'icloud' | 'legacy_sandbox';

export interface CloudStorageFileStat {
  size: number;
  birthtimeMs: number;
  mtimeMs: number;
  birthtime: Date;
  mtime: Date;
  isDirectory: () => boolean;
  isFile: () => boolean;
}

export enum CloudStorageProvider {
  /**
   * Apple iCloud, backed by CloudKit.
   * @platform ios
   */
  ICloud = 'icloud',
  GoogleDrive = 'googledrive',
}

export interface CloudStorageProviderOptions {
  [CloudStorageProvider.ICloud]: {
    /**
     * The directory scope to use for iCloud operations. Defaults to 'app_data'.
     */
    scope?: CloudStorageScope;
    /**
     * The directory mode to use for CloudStorageScope.Documents.
     * `icloud` uses the user-facing iCloud Documents directory, while
     * `legacy_sandbox` uses the local app sandbox Documents directory.
     * Defaults to `icloud`.
     */
    documentsMode?: ICloudDocumentsMode;
  };

  [CloudStorageProvider.GoogleDrive]: {
    /**
     * The directory scope to use for Google Drive operations. Defaults to 'app_data'.
     */
    scope?: CloudStorageScope;
    /**
     * The access token to use for Google Drive operations.
     */
    accessToken?: string | null;
    /**
     * Whether or not to throw an error if multiple files with the same filename are found. Defaults to false.
     */
    strictFilenames?: boolean;
    /**
     * The timeout in milliseconds after which to cancel an API request. Defaults to 3000.
     */
    timeout?: number;
  };
}

/**
 * Options for a single cloud storage provider: the iCloud options when the iCloud provider is used,
 * or the Google Drive options when the Google Drive provider is used. This is the value type of
 * {@link CloudStorageProviderOptions} and the shape accepted by `setProviderOptions` and the
 * `CloudStorage` constructor.
 */
export type CloudStorageProviderOptionsValue = CloudStorageProviderOptions[keyof CloudStorageProviderOptions];
