/**
 * BaseStorageProvider
 *
 * Abstract base class for storage providers (Strategy Pattern).
 * Subclasses implement specific storage backends (S3, GCloud, Local).
 */

class BaseStorageProvider {
  /**
   * Provider name for identification
   * @returns {string}
   */
  static get providerName() {
    throw new Error('providerName must be defined in subclass');
  }

  /**
   * Upload a file to storage
   * @param {string} _key - Storage key/path
   * @param {Buffer|ReadableStream} _data - File data
   * @param {Object} _options - Upload options
   * @param {string} [_options.contentType] - MIME type
   * @param {Object} [_options.metadata] - Additional metadata
   * @returns {Promise<{ key: string, url?: string }>}
   */
  async upload(_key, _data, _options) {
    throw new Error('upload must be implemented in subclass');
  }

  /**
   * Download a file from storage
   * @param {string} _key - Storage key/path
   * @returns {Promise<{ body: ReadableStream, contentType?: string }>}
   */
  async download(_key) {
    throw new Error('download must be implemented in subclass');
  }

  /**
   * Delete a file from storage
   * @param {string} _key - Storage key/path
   * @returns {Promise<void>}
   */
  async delete(_key) {
    throw new Error('delete must be implemented in subclass');
  }

  /**
   * Check if a file exists
   * @param {string} _key - Storage key/path
   * @returns {Promise<boolean>}
   */
  async exists(_key) {
    throw new Error('exists must be implemented in subclass');
  }

  /**
   * List files with a given prefix
   * @param {string} _prefix - Key prefix
   * @returns {Promise<string[]>} Array of keys
   */
  async list(_prefix) {
    throw new Error('list must be implemented in subclass');
  }

  /**
   * Get a signed URL for direct access (if supported)
   * @param {string} _key - Storage key/path
   * @param {number} _expiresIn - Expiration time in seconds
   * @returns {Promise<string|null>} Signed URL or null if not supported
   */
  async getSignedUrl(_key, _expiresIn) {
    return null;
  }

  /**
   * Delete multiple files
   * @param {string[]} keys - Array of keys to delete
   * @returns {Promise<void>}
   */
  async deleteMany(keys) {
    for (const key of keys) {
      await this.delete(key);
    }
  }
}

module.exports = BaseStorageProvider;
