import { d as db, s as storageConfig, b as backups } from '../../admin/create-upload-progress-table/POST-C-OoiMoW.js';
import { eq, desc } from 'drizzle-orm';
import multer from 'multer';
import path from 'path';
import fs from 'fs';
import crypto from 'crypto';
import { g as generateFileMetadata } from '../upload-encrypted/POST-CK3RHV5H.js';
import { c as createStorageProvider } from '../delete/_backupId_/DELETE-CSeC5rJf.js';
import { a as getTempDir, e as ensureDir, g as getBackupsDir } from '../../auth/setup/POST-DYMc2GPx.js';
import { g as getRecommendedCompressionLevel, c as compressFile } from '../download/_backupId_/GET-lvzGmOga.js';

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDir = path.join(getTempDir(), "uploads");
    ensureDir(uploadDir);
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    const backupId = req.body.backupId || crypto.randomBytes(16).toString("hex");
    const timestamp = Date.now();
    const ext = path.extname(file.originalname) || ".backup";
    const filename = `${backupId}_${timestamp}${ext}`;
    req.body.generatedBackupId = backupId;
    req.body.generatedFilename = filename;
    cb(null, filename);
  }
});
const fileFilter = (req, file, cb) => {
  if (file.originalname.includes("/") || file.originalname.includes("\\")) {
    const parts = file.originalname.split(/[\\/]/);
    file.originalname = parts[parts.length - 1];
    console.log("⚠️ [UPLOAD] Sanitized filename with path separators:", file.originalname);
  }
  const allowedExtensions = [".backup", ".bak", ".zip", ".tar", ".gz", ".7z", ".jpg", ".jpeg", ".png", ".mp4", ".mov"];
  const ext = path.extname(file.originalname).toLowerCase();
  if (allowedExtensions.includes(ext) || ext === "") {
    cb(null, true);
  } else {
    cb(new Error(`Invalid file type. Allowed: ${allowedExtensions.join(", ")}`));
  }
};
const upload = multer({
  storage,
  fileFilter,
  limits: {
    fileSize: 10 * 1024 * 1024 * 1024
    // 10 GB max file size
  }
});
async function handler(req, res) {
  console.log("📤 [UPLOAD] Request received");
  console.log("📤 [UPLOAD] Method:", req.method);
  console.log("📤 [UPLOAD] URL:", req.url);
  console.log("📤 [UPLOAD] Headers:", JSON.stringify(req.headers, null, 2));
  console.log("📤 [UPLOAD] Query params:", req.query);
  console.log("📤 [UPLOAD] Body fields (before multer):", Object.keys(req.body));
  upload.single("file")(req, res, async (err) => {
    if (err instanceof multer.MulterError) {
      console.error("❌ [UPLOAD] Multer error:", {
        code: err.code,
        message: err.message,
        field: err.field
      });
      return res.status(400).json({
        success: false,
        error: `Upload error: ${err.message}`,
        code: err.code
      });
    } else if (err) {
      console.error("❌ [UPLOAD] Upload error:", err.message);
      console.error("❌ [UPLOAD] Error stack:", err.stack);
      return res.status(400).json({
        success: false,
        error: err.message
      });
    }
    try {
      const { deviceId, backupType = "full", metadata, enableCompression = "true" } = req.body;
      const file = req.file;
      const shouldCompress = enableCompression === "true" || enableCompression === true;
      console.log("📤 [UPLOAD] Parsed data:", {
        deviceId,
        backupType,
        hasFile: !!file,
        fileName: file?.originalname,
        fileSize: file?.size,
        enableCompression
      });
      if (!file) {
        console.error("❌ [UPLOAD] No file in request");
        console.error("❌ [UPLOAD] Request headers:", JSON.stringify(req.headers, null, 2));
        console.error("❌ [UPLOAD] Content-Type:", req.headers["content-type"]);
        console.error("❌ [UPLOAD] Body keys:", Object.keys(req.body));
        return res.status(400).json({
          success: false,
          error: "No file uploaded - file may have been rejected by parser",
          hint: 'Check if filename contains path separators (/ or \\\\) or if field name is "file" not "chunk"'
        });
      }
      console.log("✅ [UPLOAD] File received:", {
        originalname: file.originalname,
        mimetype: file.mimetype,
        size: file.size,
        path: file.path
      });
      if (!deviceId) {
        fs.unlinkSync(file.path);
        return res.status(400).json({
          success: false,
          error: "Device ID is required"
        });
      }
      const SAFE_ID = /^[a-zA-Z0-9_-]{1,128}$/;
      if (!SAFE_ID.test(deviceId)) {
        fs.unlinkSync(file.path);
        return res.status(400).json({
          success: false,
          error: "Invalid deviceId: only letters, numbers, hyphens, and underscores are allowed"
        });
      }
      const backupId = req.body.generatedBackupId;
      const tempFilePath = file.path;
      const fileSize = file.size;
      let parsedMetadata = null;
      if (metadata) {
        try {
          parsedMetadata = JSON.parse(metadata);
        } catch (e) {
          console.warn("Failed to parse metadata:", e);
        }
      }
      let finalFilePath = tempFilePath;
      let originalSize = fileSize;
      let compressedSize = fileSize;
      let compressionRatio = 0;
      let compressionAlgorithm = null;
      if (shouldCompress) {
        const compressedPath = `${tempFilePath}.gz`;
        const compressionLevel = getRecommendedCompressionLevel(fileSize);
        try {
          const compressionResult = await compressFile(tempFilePath, compressedPath, {
            level: compressionLevel
          });
          if (compressionResult.compressedSize < originalSize) {
            finalFilePath = compressedPath;
            compressedSize = compressionResult.compressedSize;
            compressionRatio = Math.floor(compressionResult.compressionRatio);
            compressionAlgorithm = "gzip";
            fs.unlinkSync(tempFilePath);
            console.log(`Compressed backup: ${originalSize} → ${compressedSize} bytes (${compressionRatio}% saved)`);
          } else {
            fs.unlinkSync(compressedPath);
            console.log("Compression not beneficial, using original file");
          }
        } catch (compressionError) {
          console.error("Compression failed, using original file:", compressionError);
        }
      }
      const fileMetadata = await generateFileMetadata(finalFilePath);
      const configs = await db.select().from(storageConfig).where(eq(storageConfig.isActive, true)).orderBy(desc(storageConfig.createdAt)).limit(1);
      let storageProvider;
      let storageType = "local";
      let storageConfigData = { basePath: getBackupsDir() };
      if (configs.length > 0) {
        storageType = configs[0].storageType;
        storageConfigData = JSON.parse(configs[0].config);
      }
      storageProvider = createStorageProvider({
        type: storageType,
        config: storageConfigData
      });
      const storagePath = `${deviceId}/${req.body.generatedFilename}${compressionAlgorithm ? ".gz" : ""}`;
      // Guard: ensure the resolved storage path stays within the backups directory
      const resolvedStorage = path.resolve(getBackupsDir(), storagePath);
      if (!resolvedStorage.startsWith(path.resolve(getBackupsDir()) + path.sep)) {
        fs.unlinkSync(finalFilePath);
        return res.status(400).json({ success: false, error: "Invalid storage path" });
      }
      const fileBuffer = fs.readFileSync(finalFilePath);
      await storageProvider.upload(fileBuffer, storagePath);
      fs.unlinkSync(finalFilePath);
      const filePath = storagePath;
      const result = await db.insert(backups).values({
        backupId,
        deviceId,
        backupType,
        status: "completed",
        size: Math.floor(compressedSize / (1024 * 1024)),
        // Convert to MB (use compressed size)
        filePath,
        metadata: parsedMetadata ? JSON.stringify(parsedMetadata) : null,
        // Compression metadata
        compressed: compressionAlgorithm !== null,
        compressionAlgorithm,
        originalSize,
        compressedSize,
        compressionRatio,
        // Verification metadata
        hash: fileMetadata.hash,
        checksum: fileMetadata.checksum,
        verified: true,
        verifiedAt: /* @__PURE__ */ new Date(),
        startedAt: /* @__PURE__ */ new Date(),
        completedAt: /* @__PURE__ */ new Date()
      });
      const insertId = Number(result[0].insertId);
      const newBackup = await db.select().from(backups).where(eq(backups.id, insertId)).limit(1);
      if (newBackup.length === 0) {
        return res.status(500).json({
          success: false,
          error: "Failed to retrieve created backup"
        });
      }
      console.log("✅ [UPLOAD] Backup completed successfully:", {
        backupId: newBackup[0].backupId,
        deviceId: newBackup[0].deviceId,
        size: newBackup[0].size,
        compressed: newBackup[0].compressed,
        filePath: newBackup[0].filePath
      });
      res.status(201).json({
        success: true,
        backup: newBackup[0],
        message: "Backup uploaded successfully"
      });
    } catch (error) {
      console.error("Backup upload error:", error);
      if (req.file && fs.existsSync(req.file.path)) {
        try {
          fs.unlinkSync(req.file.path);
        } catch (e) {
          console.error("Failed to clean up temp file:", e);
        }
      }
      res.status(500).json({
        success: false,
        error: "Failed to process backup upload",
        message: String(error)
      });
    }
  });
}

export { handler as h };
