import { CancellationContext, ERRORS, EVENTS } from '../utils'
import { BaseHandler } from './BaseHandler'

import type http from 'node:http'

export class DeleteHandler extends BaseHandler {
  /**
   * 处理DELETE请求的核心方法
   * @param req HTTP请求对象，包含请求头、请求体等信息
   * @param res HTTP响应对象，用于返回响应状态和数据
   * @param context 取消上下文，用于处理请求取消逻辑
   * @returns 返回处理后的HTTP响应对象
   * 
   * 技术原理：
   * - 通过HTTP DELETE方法删除指定资源
   * - 使用锁机制保证并发安全
   * - 支持自定义请求处理钩子
   * 
   * 优化建议：
   * - 可考虑添加批量删除支持
   * - 可优化锁机制，使用更细粒度的锁
   */
  async send(
    req: http.IncomingMessage,
    res: http.ServerResponse,
    context: CancellationContext
  ) {
    // 从请求中提取文件ID
    const id = this.getFileIdFromRequest(req)
    // 文件ID不存在时抛出异常
    if (!id) {
      throw ERRORS.FILE_NOT_FOUND
    }

    // 执行自定义的请求处理钩子
    if (this.options.onIncomingRequest) {
      await this.options.onIncomingRequest(req, res, id)
    }

    // 获取文件操作锁，保证并发安全
    const lock = await this.acquireLock(req, id, context)
    try {
      // 检查是否禁止删除已完成的上传
      if (this.options.disableTerminationForFinishedUploads) {
        const upload = await this.store.getUpload(id)
        // 上传已完成时抛出异常
        if (upload.offset === upload.size) {
          throw ERRORS.INVALID_TERMINATION
        }
      }

      // 从存储中删除指定文件
      await this.store.remove(id)
    } finally {
      // 无论成功与否，最终都要释放锁
      await lock.unlock()
    }
    // 返回204 No Content响应
    const writtenRes = this.write(res, 204, {})
    // 触发删除完成事件
    this.emit(EVENTS.POST_TERMINATE, req, writtenRes, id)
    return writtenRes
  }
}
