'use strict';

var chunk25OFOKNF_js = require('./chunk-25OFOKNF.js');
var chunkZRAW3HXA_js = require('./chunk-ZRAW3HXA.js');
var events = require('events');
var uuid = require('uuid');
var crypto = require('crypto');
var path2 = require('path');

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n.default = e;
  return Object.freeze(n);
}

var path2__namespace = /*#__PURE__*/_interopNamespace(path2);

var MIME_TYPES = {
  // 图片
  ".jpg": "image/jpeg",
  ".jpeg": "image/jpeg",
  ".png": "image/png",
  ".gif": "image/gif",
  ".webp": "image/webp",
  ".svg": "image/svg+xml",
  ".bmp": "image/bmp",
  ".ico": "image/x-icon",
  // 视频
  ".mp4": "video/mp4",
  ".avi": "video/x-msvideo",
  ".mov": "video/quicktime",
  ".wmv": "video/x-ms-wmv",
  ".flv": "video/x-flv",
  ".mkv": "video/x-matroska",
  ".webm": "video/webm",
  // 音频
  ".mp3": "audio/mpeg",
  ".wav": "audio/wav",
  ".ogg": "audio/ogg",
  ".m4a": "audio/mp4",
  ".flac": "audio/flac",
  ".aac": "audio/aac",
  // 文档
  ".pdf": "application/pdf",
  ".doc": "application/msword",
  ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  ".xls": "application/vnd.ms-excel",
  ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  ".ppt": "application/vnd.ms-powerpoint",
  ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
  ".txt": "text/plain",
  ".rtf": "application/rtf",
  // 压缩文件
  ".zip": "application/zip",
  ".rar": "application/x-rar-compressed",
  ".7z": "application/x-7z-compressed",
  ".tar": "application/x-tar",
  ".gz": "application/gzip",
  // 代码文件
  ".js": "application/javascript",
  ".json": "application/json",
  ".xml": "application/xml",
  ".html": "text/html",
  ".css": "text/css",
  ".ts": "application/typescript",
  // 其他
  ".csv": "text/csv",
  ".md": "text/markdown"
};
function getMimeType(filename) {
  const ext = path2__namespace.extname(filename).toLowerCase();
  return MIME_TYPES[ext] || "application/octet-stream";
}

// src/universalFile/server/UniversalFileService.ts
var logger = chunk25OFOKNF_js.createLogger("UniversalFileService");
var UniversalFileService = class extends events.EventEmitter {
  constructor(config) {
    super();
    this.storageProviders = /* @__PURE__ */ new Map();
    this.cdnProviders = /* @__PURE__ */ new Map();
    this.fileProcessors = /* @__PURE__ */ new Map();
    this.uploadProgressMap = /* @__PURE__ */ new Map();
    this.metadataCache = /* @__PURE__ */ new Map();
    this.urlCache = /* @__PURE__ */ new Map();
    this.processingQueue = [];
    this.isProcessingQueueRunning = false;
    this.config = config;
    if (this.config.persistence?.enabled && this.config.persistence.repository) {
      this.setupPersistenceListeners();
    }
  }
  // ============= 持久化设置 =============
  /**
   * 设置数据库持久化监听器
   *
   * 当文件上传完成或删除时，自动触发数据库操作
   */
  setupPersistenceListeners() {
    const { repository, autoPersist = true } = this.config.persistence;
    if (!autoPersist) {
      logger.info("\u2699\uFE0F [UniversalFileService] \u81EA\u52A8\u6301\u4E45\u5316\u5DF2\u7981\u7528");
      return;
    }
    logger.info("\u2705 [UniversalFileService] \u5DF2\u542F\u7528\u6570\u636E\u5E93\u6301\u4E45\u5316\uFF0C\u81EA\u52A8\u76D1\u542C\u6587\u4EF6\u4E8B\u4EF6");
    this.on("upload:complete", async (fileId, data) => {
      try {
        const metadata = data.metadata || data;
        await repository.save(metadata);
        logger.info("\u{1F4BE} [Persistence] \u6587\u4EF6\u5143\u6570\u636E\u5DF2\u81EA\u52A8\u4FDD\u5B58: " + fileId);
      } catch (error) {
        logger.error("\u274C [Persistence] \u4FDD\u5B58\u5931\u8D25: " + fileId, error);
      }
    });
    this.on("file:deleted", async (fileId) => {
      try {
        await repository.delete(fileId);
        logger.info("\u{1F5D1}\uFE0F [Persistence] \u6587\u4EF6\u5143\u6570\u636E\u5DF2\u81EA\u52A8\u5220\u9664: " + fileId);
      } catch (error) {
        logger.error("\u274C [Persistence] \u5220\u9664\u5931\u8D25: " + fileId, error);
      }
    });
    this.on("files:batch-deleted", async (fileIds) => {
      try {
        await repository.batchDelete(fileIds);
        logger.info("\u{1F5D1}\uFE0F [Persistence] \u6279\u91CF\u5220\u9664\u5143\u6570\u636E: " + fileIds.length + " \u4E2A\u6587\u4EF6");
      } catch (error) {
        logger.error(`\u274C [Persistence] \u6279\u91CF\u5220\u9664\u5931\u8D25`, error);
      }
    });
  }
  // ============= 初始化方法 =============
  /**
   * 初始化文件服务
   */
  async initialize() {
    logger.info("\u{1F680} [UniversalFileService] \u5F00\u59CB\u521D\u59CB\u5316\u6587\u4EF6\u670D\u52A1...");
    try {
      await this.validateConfiguration();
      await this.initializeStorageProviders();
      await this.initializeCDNProviders();
      await this.initializeFileProcessors();
      logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u670D\u52A1\u521D\u59CB\u5316\u5B8C\u6210");
    } catch (error) {
      console.error("\u274C [UniversalFileService] \u6587\u4EF6\u670D\u52A1\u521D\u59CB\u5316\u5931\u8D25:", error);
      throw error;
    }
  }
  /**
   * 重新初始化存储提供者（支持配置热更新）
   */
  async reinitializeStorageProviders() {
    logger.info("\u{1F504} [UniversalFileService] \u91CD\u65B0\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005...");
    try {
      for (const [type, provider] of this.storageProviders) {
        if ("reinitialize" in provider) {
          try {
            logger.info("\u{1F504} [UniversalFileService] \u91CD\u65B0\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005: " + type + "...");
            const config = this.config.storageProviders?.[type];
            if (config) {
              await provider.reinitialize(config);
              logger.info("\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210: " + type);
            } else {
              logger.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u914D\u7F6E\u4E0D\u5B58\u5728: " + type);
            }
          } catch (error) {
            logger.error("\u274C [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5931\u8D25: " + type, error);
          }
        }
      }
      logger.info("\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210");
    } catch (error) {
      console.error("\u274C [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5931\u8D25:", error);
      throw error;
    }
  }
  /**
   * 注册存储提供者
   */
  registerStorageProvider(provider) {
    this.storageProviders.set(provider.type, provider);
    logger.info("\u{1F4E6} [UniversalFileService] \u6CE8\u518C\u5B58\u50A8\u63D0\u4F9B\u8005: " + provider.type);
  }
  /**
   * 注册CDN提供者
   */
  registerCDNProvider(provider) {
    this.cdnProviders.set(provider.type, provider);
    logger.info("\u{1F310} [UniversalFileService] \u6CE8\u518CCDN\u63D0\u4F9B\u8005: " + provider.type);
  }
  /**
   * 注册文件处理器
   */
  registerFileProcessor(processor) {
    this.fileProcessors.set(processor.type, processor);
    logger.info("\u2699\uFE0F [UniversalFileService] \u6CE8\u518C\u6587\u4EF6\u5904\u7406\u5668: " + processor.type);
  }
  // ============= 核心文件操作方法 =============
  /**
   * 上传文件
   */
  async uploadFile(fileInfo, storageType, onProgress) {
    const fileId = uuid.v4();
    const startTime = Date.now();
    logger.info("\u{1F4E4} [UniversalFileService] \u5F00\u59CB\u4E0A\u4F20\u6587\u4EF6: " + fileInfo.file.name + ", ID: " + fileId);
    try {
      await this.validateFile(fileInfo.file);
      const progress = {
        fileId,
        status: "pending",
        progress: 0,
        uploadedBytes: 0,
        totalBytes: fileInfo.file.size,
        speed: 0,
        remainingTime: 0
      };
      this.uploadProgressMap.set(fileId, progress);
      this.emitFileEvent("upload:start", fileId, { fileName: fileInfo.file.name });
      const metadata = await this.generateFileMetadata(fileId, fileInfo);
      const selectedStorageType = storageType || this.config.defaultStorage;
      let storageProvider = this.storageProviders.get(selectedStorageType);
      if (!storageProvider) {
        logger.info(
          "\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005 " + selectedStorageType + " \u4E0D\u53EF\u7528\uFF0C\u5C1D\u8BD5\u4F7F\u7528OSS"
        );
        storageProvider = this.storageProviders.get("aliyun-oss");
        if (!storageProvider) {
          logger.info(`\u26A0\uFE0F [UniversalFileService] OSS\u4E0D\u53EF\u7528\uFF0C\u56DE\u9000\u5230\u672C\u5730\u5B58\u50A8`);
          storageProvider = this.storageProviders.get("local");
        }
      }
      if (!storageProvider) {
        throw new chunkZRAW3HXA_js.StorageProviderError(`\u6CA1\u6709\u53EF\u7528\u7684\u5B58\u50A8\u63D0\u4F9B\u8005`);
      }
      const storagePath = this.generateStoragePath(metadata);
      progress.status = "uploading";
      progress.progress = 10;
      this.uploadProgressMap.set(fileId, progress);
      onProgress?.(progress);
      this.emitFileEvent("upload:progress", fileId, { progress: progress.progress });
      const uploadResult = await storageProvider.upload(fileInfo, storagePath);
      if (!uploadResult.success) {
        throw new chunkZRAW3HXA_js.FileUploadError("\u4E0A\u4F20\u5931\u8D25: " + uploadResult.error);
      }
      metadata.storagePath = uploadResult.path || storagePath;
      metadata.storageProvider = selectedStorageType;
      if (this.config.defaultCDN !== "none") {
        const cdnProvider = this.cdnProviders.get(this.config.defaultCDN);
        if (cdnProvider && uploadResult.url) {
          metadata.cdnUrl = await cdnProvider.generateUrl(uploadResult.url);
        }
      }
      progress.status = fileInfo.needsProcessing ? "processing" : "completed";
      progress.progress = fileInfo.needsProcessing ? 70 : 100;
      this.uploadProgressMap.set(fileId, progress);
      onProgress?.(progress);
      if (fileInfo.needsProcessing && fileInfo.processingOptions) {
        await this.queueFileProcessing(metadata, fileInfo.processingOptions);
      }
      this.cacheMetadata(metadata);
      progress.status = "completed";
      progress.progress = 100;
      this.uploadProgressMap.set(fileId, progress);
      onProgress?.(progress);
      const uploadTime = Date.now() - startTime;
      logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210: " + fileId + ", \u8017\u65F6: " + uploadTime + "ms");
      this.emitFileEvent("upload:complete", fileId, {
        fileName: fileInfo.file.name,
        size: fileInfo.file.size,
        uploadTime
      });
      return metadata;
    } catch (error) {
      console.error("\u274C [UniversalFileService] \u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: " + fileId + ":", error);
      const progress = this.uploadProgressMap.get(fileId);
      if (progress) {
        progress.status = "failed";
        progress.error = error instanceof Error ? error.message : "\u4E0A\u4F20\u5931\u8D25";
        this.uploadProgressMap.set(fileId, progress);
        onProgress?.(progress);
      }
      this.emitFileEvent(
        "upload:error",
        fileId,
        void 0,
        error instanceof Error ? error.message : "\u4E0A\u4F20\u5931\u8D25"
      );
      throw error;
    } finally {
      setTimeout(
        () => {
          this.uploadProgressMap.delete(fileId);
        },
        5 * 60 * 1e3
      );
    }
  }
  /**
   * 下载文件
   */
  async downloadFile(fileId, userId) {
    logger.info("\u{1F4E5} [UniversalFileService] \u5F00\u59CB\u4E0B\u8F7D\u6587\u4EF6: " + fileId);
    try {
      this.emitFileEvent("download:start", fileId);
      const metadata = await this.getFileMetadata(fileId);
      if (!metadata) {
        throw new chunkZRAW3HXA_js.FileUploadError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + fileId);
      }
      await this.checkFileAccess(metadata, userId);
      const storageProvider = this.storageProviders.get(metadata.storageProvider);
      if (!storageProvider) {
        throw new chunkZRAW3HXA_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u4E0D\u5B58\u5728: " + metadata.storageProvider);
      }
      const fileBuffer = await storageProvider.download(metadata.storagePath);
      if (this.config.persistence?.enabled) {
        await this.updateAccessStats(fileId);
      }
      logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u4E0B\u8F7D\u5B8C\u6210: " + fileId);
      this.emitFileEvent("download:complete", fileId, { size: fileBuffer.length });
      return fileBuffer;
    } catch (error) {
      console.error("\u274C [UniversalFileService] \u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25: " + fileId + ":", error);
      this.emitFileEvent("download:error", fileId, void 0, error instanceof Error ? error.message : "\u4E0B\u8F7D\u5931\u8D25");
      throw error;
    }
  }
  /**
   * 删除文件
   */
  async deleteFile(fileId, userId) {
    logger.info("\u{1F5D1}\uFE0F [UniversalFileService] \u5F00\u59CB\u5220\u9664\u6587\u4EF6: " + fileId);
    try {
      const metadata = await this.getFileMetadata(fileId);
      if (!metadata) {
        throw new chunkZRAW3HXA_js.FileUploadError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + fileId);
      }
      await this.checkFileDeleteAccess(metadata, userId);
      const storageProvider = this.storageProviders.get(metadata.storageProvider);
      if (!storageProvider) {
        throw new chunkZRAW3HXA_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u4E0D\u5B58\u5728: " + metadata.storageProvider);
      }
      const deleteResult = await storageProvider.delete(metadata.storagePath);
      if (!deleteResult.success) {
        console.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u6587\u4EF6\u5220\u9664\u5931\u8D25: " + deleteResult.error);
      }
      if (this.config.persistence?.enabled) {
        await this.deleteFileMetadata(fileId);
      }
      this.clearMetadataCache(fileId);
      logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u5220\u9664\u5B8C\u6210: " + fileId);
      this.emitFileEvent("delete:complete", fileId);
      this.emit("file:deleted", fileId);
    } catch (error) {
      console.error("\u274C [UniversalFileService] \u6587\u4EF6\u5220\u9664\u5931\u8D25: " + fileId + ":", error);
      this.emitFileEvent("delete:error", fileId, void 0, error instanceof Error ? error.message : "\u5220\u9664\u5931\u8D25");
      throw error;
    }
  }
  /**
   * 获取文件访问URL
   */
  async getFileUrl(fileId, userId, expiresIn) {
    const cacheKey = fileId + "_" + (userId || "public") + "_" + (expiresIn || 0);
    const cached = this.urlCache.get(cacheKey);
    if (cached && cached.expires > Date.now()) {
      return cached.url;
    }
    const metadata = await this.getFileMetadata(fileId);
    if (!metadata) {
      throw new chunkZRAW3HXA_js.FileUploadError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + fileId);
    }
    await this.checkFileAccess(metadata, userId);
    let url;
    if (metadata.cdnUrl) {
      url = metadata.cdnUrl;
    } else {
      const storageProvider = this.storageProviders.get(metadata.storageProvider);
      if (!storageProvider) {
        throw new chunkZRAW3HXA_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u4E0D\u5B58\u5728: " + metadata.storageProvider);
      }
      url = await storageProvider.getAccessUrl(metadata.storagePath, expiresIn);
    }
    const cacheExpires = Date.now() + (this.config.cache?.urlTTL || 1800) * 1e3;
    this.urlCache.set(cacheKey, { url, expires: cacheExpires });
    return url;
  }
  /**
   * 获取文件元数据
   */
  async getFileMetadata(fileId) {
    const cached = this.metadataCache.get(fileId);
    if (cached && cached.expires > Date.now()) {
      return cached.data;
    }
    if (this.config.persistence?.enabled && this.config.persistence.repository) {
      try {
        const metadata = await this.config.persistence.repository.get(fileId);
        if (metadata) {
          this.cacheMetadata(metadata);
        }
        return metadata;
      } catch (error) {
        console.error("\u274C [UniversalFileService] \u67E5\u8BE2\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25:", error);
        return null;
      }
    }
    logger.warn("\u26A0\uFE0F [UniversalFileService] \u6301\u4E45\u5316\u672A\u542F\u7528,\u65E0\u6CD5\u67E5\u8BE2\u6587\u4EF6\u5143\u6570\u636E: " + fileId);
    return null;
  }
  /**
   * 查询文件列表
   */
  async queryFiles(options) {
    if (!this.config.persistence?.enabled || !this.config.persistence.repository) {
      logger.warn("\u26A0\uFE0F [UniversalFileService] \u6301\u4E45\u5316\u672A\u542F\u7528,\u65E0\u6CD5\u67E5\u8BE2\u6587\u4EF6\u5217\u8868");
      return {
        items: [],
        total: 0,
        page: options.page || 1,
        pageSize: options.pageSize || 20,
        totalPages: 0,
        hasNext: false,
        hasPrev: false
      };
    }
    try {
      const result = await this.config.persistence.repository.query(options);
      const hasNext = result.page < result.totalPages;
      const hasPrev = result.page > 1;
      return {
        ...result,
        hasNext,
        hasPrev
      };
    } catch (error) {
      console.error("\u274C [UniversalFileService] \u67E5\u8BE2\u6587\u4EF6\u5217\u8868\u5931\u8D25:", error);
      throw error;
    }
  }
  /**
   * 批量删除文件
   */
  async batchDeleteFiles(fileIds, userId) {
    const result = {
      successCount: 0,
      failureCount: 0,
      failures: []
    };
    for (const fileId of fileIds) {
      try {
        await this.deleteFile(fileId, userId);
        result.successCount++;
      } catch (error) {
        result.failureCount++;
        result.failures.push({
          fileId,
          error: error instanceof Error ? error.message : "\u5220\u9664\u5931\u8D25"
        });
      }
    }
    if (result.successCount > 0) {
      this.emit("files:batch-deleted", fileIds.filter((_, i) => i < result.successCount));
    }
    return result;
  }
  /**
   * 获取上传进度
   */
  getUploadProgress(fileId) {
    return this.uploadProgressMap.get(fileId);
  }
  // ============= 事件处理方法 =============
  /**
   * 监听文件事件
   */
  onFileEvent(eventType, listener) {
    this.on(eventType, listener);
  }
  /**
   * 移除文件事件监听器
   */
  offFileEvent(eventType, listener) {
    this.off(eventType, listener);
  }
  // ============= 私有方法 =============
  /**
   * 验证配置是否完整
   */
  async validateConfiguration() {
    logger.info("\u{1F50D} [UniversalFileService] \u9A8C\u8BC1\u914D\u7F6E\u6587\u4EF6...");
    if (!this.config) {
      throw new Error("\u6587\u4EF6\u670D\u52A1\u914D\u7F6E\u4E3A\u7A7A");
    }
    if (!this.config.storage) {
      throw new Error("\u5B58\u50A8\u914D\u7F6E\u4E3A\u7A7A");
    }
    if (this.config.storage.type === "aliyun-oss") {
      const ossConfig = this.config.storage;
      if (!ossConfig.accessKeyId || !ossConfig.accessKeySecret || !ossConfig.bucket || !ossConfig.region) {
        logger.warn("\u26A0\uFE0F [UniversalFileService] OSS\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF0C\u7B49\u5F85\u914D\u7F6E\u52A0\u8F7D...");
        const maxRetries = 30;
        const retryInterval = 1e3;
        for (let i = 0; i < maxRetries; i++) {
          await new Promise((resolve) => setTimeout(resolve, retryInterval));
          const updatedConfig = this.config.storage;
          if (updatedConfig.accessKeyId && updatedConfig.accessKeySecret && updatedConfig.bucket && updatedConfig.region) {
            logger.info("\u2705 [UniversalFileService] OSS\u914D\u7F6E\u52A0\u8F7D\u5B8C\u6210");
            break;
          }
          if (i === maxRetries - 1) {
            throw new Error("OSS\u914D\u7F6E\u52A0\u8F7D\u8D85\u65F6\uFF1A\u7F3A\u5C11\u5FC5\u9700\u7684\u914D\u7F6E\u9879 (accessKeyId, accessKeySecret, bucket, region)");
          }
          logger.debug("\u7B49\u5F85OSS\u914D\u7F6E\u52A0\u8F7D\u4E2D... (" + (i + 1) + "/" + maxRetries + ")");
        }
      }
    }
    if (!this.config.defaultStorage) {
      this.config.defaultStorage = this.config.storage.type;
    }
    logger.info("\u2705 [UniversalFileService] \u914D\u7F6E\u9A8C\u8BC1\u5B8C\u6210");
  }
  async initializeStorageProviders() {
    logger.info("\u{1F4E6} [UniversalFileService] \u5F00\u59CB\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005...");
    if (this.storageProviders.size === 0) {
      await this.registerDefaultStorageProviders();
    }
    if (this.config.storageProviders) {
      for (const [type, config] of Object.entries(this.config.storageProviders)) {
        if (config && config.enabled) {
          const provider = this.storageProviders.get(type);
          if (provider) {
            try {
              await provider.initialize(config);
              logger.info("\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5B8C\u6210: " + type);
            } catch (error) {
              console.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5931\u8D25: " + type + ":", error);
            }
          } else {
            console.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u6CE8\u518C: " + type);
          }
        }
      }
    }
  }
  async registerDefaultStorageProviders() {
    logger.info("\u{1F4E6} [UniversalFileService] \u6CE8\u518C\u9ED8\u8BA4\u5B58\u50A8\u63D0\u4F9B\u8005...");
    try {
      if (this.config.storage) {
        if (this.config.storage.type === "aliyun-oss" && this.config.storage.enabled) {
          const { AliyunOSSProvider } = await import('./AliyunOSSProvider-KSYW2IOG.js');
          const ossProvider = new AliyunOSSProvider();
          this.registerStorageProvider(ossProvider);
          logger.info("\u2705 [UniversalFileService] \u963F\u91CC\u4E91OSS\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
        } else if (this.config.storage.type === "local" && this.config.storage.enabled) {
          const { LocalStorageProvider } = await import('./LocalStorageProvider-SSRW3ZJW.js');
          const localProvider = new LocalStorageProvider();
          this.registerStorageProvider(localProvider);
          logger.info("\u2705 [UniversalFileService] \u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
        }
      }
      if (this.storageProviders.size === 0) {
        const { LocalStorageProvider } = await import('./LocalStorageProvider-SSRW3ZJW.js');
        const fallbackProvider = new LocalStorageProvider();
        this.registerStorageProvider(fallbackProvider);
        logger.info("\u2705 [UniversalFileService] \u5DF2\u6CE8\u518C\u5907\u7528\u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005");
      }
    } catch (error) {
      console.warn("\u26A0\uFE0F [UniversalFileService] \u6CE8\u518C\u9ED8\u8BA4\u5B58\u50A8\u63D0\u4F9B\u8005\u5931\u8D25:", error);
      throw new Error("\u65E0\u6CD5\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005");
    }
  }
  async initializeCDNProviders() {
    if (this.config.cdn && this.config.cdn.enabled) {
      logger.info("\u2705 [UniversalFileService] CDN\u914D\u7F6E\u5DF2\u542F\u7528: " + this.config.cdn.type);
    }
  }
  async initializeFileProcessors() {
    for (const processor of Array.from(this.fileProcessors.values())) {
      await processor.initialize();
      logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u5904\u7406\u5668\u521D\u59CB\u5316\u5B8C\u6210: " + processor.type);
    }
  }
  async validateFile(file) {
    if (this.config.maxFileSize && file.size > this.config.maxFileSize) {
      throw new chunkZRAW3HXA_js.FileUploadError("\u6587\u4EF6\u5927\u5C0F\u8D85\u8FC7\u9650\u5236: " + file.size + " > " + this.config.maxFileSize);
    }
    const mimeType = file.type || getMimeType(file.name);
    if (this.config.allowedMimeTypes && this.config.allowedMimeTypes.length > 0 && !this.config.allowedMimeTypes.includes(mimeType)) {
      throw new chunkZRAW3HXA_js.FileUploadError("\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: " + mimeType);
    }
  }
  async generateFileMetadata(fileId, fileInfo) {
    const now = /* @__PURE__ */ new Date();
    const mimeType = fileInfo.file.type || getMimeType(fileInfo.file.name);
    const extension = path2__namespace.extname(fileInfo.file.name).toLowerCase();
    const hash = await this.generateFileHash(fileInfo.file);
    return {
      id: fileId,
      originalName: fileInfo.file.name,
      storageName: fileId + extension,
      size: fileInfo.file.size,
      mimeType,
      extension,
      hash,
      uploadTime: now,
      permission: fileInfo.permission || "public",
      uploaderId: fileInfo.metadata?.uploadedBy || "system",
      moduleId: fileInfo.moduleId,
      businessId: fileInfo.businessId,
      storageProvider: this.config.defaultStorage || "local",
      storagePath: "",
      accessCount: 0,
      metadata: fileInfo.metadata || {}
    };
  }
  generateStoragePath(metadata) {
    const date = /* @__PURE__ */ new Date();
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return metadata.moduleId + "/" + year + "/" + month + "/" + day + "/" + metadata.storageName;
  }
  async generateFileHash(file) {
    const buffer = await file.arrayBuffer();
    const hash = crypto.createHash("sha256");
    hash.update(Buffer.from(buffer));
    return hash.digest("hex");
  }
  async queueFileProcessing(metadata, options) {
    if (!this.config.processors?.length || 0 > 0) {
      return;
    }
    const processor = this.fileProcessors.get(options.type);
    if (!processor) {
      console.warn("\u26A0\uFE0F [UniversalFileService] \u6587\u4EF6\u5904\u7406\u5668\u4E0D\u5B58\u5728: " + options.type);
      return;
    }
    if (this.processingQueue.length >= 1e3) {
      throw new chunkZRAW3HXA_js.FileProcessingError("\u5904\u7406\u961F\u5217\u5DF2\u6EE1");
    }
    this.processingQueue.push({
      fileId: metadata.id,
      processor,
      inputPath: metadata.storagePath,
      outputPath: this.generateProcessedPath(metadata, options),
      options
    });
    if (!this.isProcessingQueueRunning) {
      this.processFileQueue();
    }
  }
  generateProcessedPath(metadata, options) {
    const basePath = metadata.storagePath;
    const extension = path2__namespace.extname(basePath);
    const basename = basePath.replace(extension, "");
    return basename + "_processed" + extension;
  }
  async processFileQueue() {
    if (this.isProcessingQueueRunning || this.processingQueue.length === 0) {
      return;
    }
    this.isProcessingQueueRunning = true;
    while (this.processingQueue.length > 0) {
      const task = this.processingQueue.shift();
      if (!task) break;
      try {
        this.emitFileEvent("processing:start", task.fileId);
        const result = await task.processor.process(task.inputPath, task.outputPath, task.options);
        if (result.success) {
          this.emitFileEvent("processing:complete", task.fileId, result);
        } else {
          this.emitFileEvent("processing:error", task.fileId, void 0, result.error);
        }
      } catch (error) {
        console.error("\u274C [UniversalFileService] \u6587\u4EF6\u5904\u7406\u5931\u8D25: " + task.fileId + ":", error);
        this.emitFileEvent(
          "processing:error",
          task.fileId,
          void 0,
          error instanceof Error ? error.message : "\u5904\u7406\u5931\u8D25"
        );
      }
    }
    this.isProcessingQueueRunning = false;
  }
  cacheMetadata(metadata) {
    const expires = Date.now() + (this.config.cache?.metadataTTL || 3600) * 1e3;
    this.metadataCache.set(metadata.id, { data: metadata, expires });
  }
  clearMetadataCache(fileId) {
    this.metadataCache.delete(fileId);
  }
  emitFileEvent(type, fileId, data, error) {
    const event = {
      type,
      fileId,
      timestamp: /* @__PURE__ */ new Date(),
      data,
      error
    };
    this.emit(type, event);
    this.emit("*", event);
  }
  // ============= 数据库操作私有方法 =============
  /**
   * 保存文件元数据到数据库 (通过持久化仓储)
   */
  async saveFileMetadata(metadata) {
    if (!this.config.persistence?.enabled || !this.config.persistence.repository) {
      logger.warn("\u26A0\uFE0F [UniversalFileService] \u6301\u4E45\u5316\u672A\u542F\u7528,\u8DF3\u8FC7\u4FDD\u5B58\u5143\u6570\u636E");
      return;
    }
    try {
      await this.config.persistence.repository.save(metadata);
      logger.info("\u{1F4BE} [UniversalFileService] \u6587\u4EF6\u5143\u6570\u636E\u4FDD\u5B58\u6210\u529F:", metadata.id);
    } catch (error) {
      console.error("\u274C [UniversalFileService] \u4FDD\u5B58\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25:", error);
      throw new chunkZRAW3HXA_js.FileUploadError(
        "\u4FDD\u5B58\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
      );
    }
  }
  /**
   * 从数据库删除文件元数据 (通过持久化仓储)
   */
  async deleteFileMetadata(fileId) {
    if (!this.config.persistence?.enabled || !this.config.persistence.repository) {
      return;
    }
    try {
      await this.config.persistence.repository.delete(fileId);
      logger.info("\u{1F5D1}\uFE0F [UniversalFileService] \u6587\u4EF6\u5143\u6570\u636E\u5220\u9664\u6210\u529F:", fileId);
    } catch (error) {
      console.error("\u274C [UniversalFileService] \u5220\u9664\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25:", error);
      throw new chunkZRAW3HXA_js.FileUploadError(
        "\u5220\u9664\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
      );
    }
  }
  /**
   * 更新访问统计
   */
  async updateAccessStats(fileId) {
    logger.info("\u{1F4CA} [UniversalFileService] \u9700\u8981\u66F4\u65B0\u8BBF\u95EE\u7EDF\u8BA1:", fileId);
  }
  /**
   * 检查文件访问权限
   */
  async checkFileAccess(metadata, userId) {
    if (metadata.permission === "public") {
      return;
    }
    if (metadata.permission === "private" && metadata.uploaderId !== userId) {
      throw new chunkZRAW3HXA_js.FileUploadError("\u65E0\u6743\u9650\u8BBF\u95EE\u6B64\u6587\u4EF6");
    }
    if (metadata.permission === "authenticated" && !userId) {
      throw new chunkZRAW3HXA_js.FileUploadError("\u9700\u8981\u767B\u5F55\u624D\u80FD\u8BBF\u95EE\u6B64\u6587\u4EF6");
    }
  }
  /**
   * 检查文件删除权限
   */
  async checkFileDeleteAccess(metadata, userId) {
    if (metadata.uploaderId !== userId) {
      throw new chunkZRAW3HXA_js.FileUploadError("\u65E0\u6743\u9650\u5220\u9664\u6B64\u6587\u4EF6");
    }
  }
  /**
   * 检查服务是否完全可用（包括存储提供者）
   */
  isFullyInitialized() {
    const hasStorageProvider = Array.from(this.storageProviders.values()).some(
      (provider) => provider.type === "aliyun-oss" || provider.type === "local"
    );
    return hasStorageProvider;
  }
  /**
   * 等待服务完全初始化（带超时）
   */
  async waitForInitialization(timeoutMs = 3e4) {
    const startTime = Date.now();
    while (!this.isFullyInitialized()) {
      if (Date.now() - startTime > timeoutMs) {
        throw new Error("\u670D\u52A1\u521D\u59CB\u5316\u8D85\u65F6 (" + timeoutMs + "ms)");
      }
      await new Promise((resolve) => setTimeout(resolve, 100));
    }
    logger.info("\u2705 [UniversalFileService] \u670D\u52A1\u5B8C\u5168\u521D\u59CB\u5316\u5C31\u7EEA");
  }
};

exports.UniversalFileService = UniversalFileService;
exports.getMimeType = getMimeType;
//# sourceMappingURL=chunk-YMS6BPXS.js.map
//# sourceMappingURL=chunk-YMS6BPXS.js.map