import { d as db, b as backups } from '../../admin/create-upload-progress-table/POST-C-OoiMoW.js';
import { eq } from 'drizzle-orm';
import multer from 'multer';
import path from 'path';
import fs from 'fs';
import crypto from 'crypto';
import { e as encryptFile } from '../download-decrypted/_backupId_/GET-D4n5HIiX.js';
import { a as getTempDir, e as ensureDir, g as getBackupsDir } from '../../auth/setup/POST-DYMc2GPx.js';

async function generateFileHash(filePath) {
  return new Promise((resolve, reject) => {
    const hash = crypto.createHash("sha256");
    const stream = fs.createReadStream(filePath);
    stream.on("data", (chunk) => hash.update(chunk));
    stream.on("end", () => resolve(hash.digest("hex")));
    stream.on("error", reject);
  });
}
async function generateFileChecksum(filePath) {
  return new Promise((resolve, reject) => {
    let crc = 4294967295;
    const stream = fs.createReadStream(filePath);
    stream.on("data", (chunk) => {
      for (let i = 0; i < chunk.length; i++) {
        crc = crc32Table[(crc ^ chunk[i]) & 255] ^ crc >>> 8;
      }
    });
    stream.on("end", () => {
      crc = (crc ^ 4294967295) >>> 0;
      resolve(crc.toString(16).padStart(8, "0"));
    });
    stream.on("error", reject);
  });
}
async function generateFileMetadata(filePath) {
  const stats = fs.statSync(filePath);
  const [hash, checksum] = await Promise.all([
    generateFileHash(filePath),
    generateFileChecksum(filePath)
  ]);
  return {
    hash,
    checksum,
    size: stats.size
  };
}
async function verifyFileIntegrity(filePath, expectedMetadata) {
  try {
    if (!fs.existsSync(filePath)) {
      return {
        valid: false,
        error: "File not found"
      };
    }
    const stats = fs.statSync(filePath);
    if (stats.size !== expectedMetadata.size) {
      return {
        valid: false,
        size: stats.size,
        error: `Size mismatch: expected ${expectedMetadata.size}, got ${stats.size}`
      };
    }
    const [actualHash, actualChecksum] = await Promise.all([
      generateFileHash(filePath),
      generateFileChecksum(filePath)
    ]);
    const hashValid = actualHash === expectedMetadata.hash;
    const checksumValid = actualChecksum === expectedMetadata.checksum;
    if (!hashValid || !checksumValid) {
      return {
        valid: false,
        hash: actualHash,
        checksum: actualChecksum,
        size: stats.size,
        error: !hashValid ? "Hash mismatch" : "Checksum mismatch"
      };
    }
    return {
      valid: true,
      hash: actualHash,
      checksum: actualChecksum,
      size: stats.size
    };
  } catch (error) {
    return {
      valid: false,
      error: String(error)
    };
  }
}
const crc32Table = new Uint32Array(256);
for (let i = 0; i < 256; i++) {
  let crc = i;
  for (let j = 0; j < 8; j++) {
    crc = crc & 1 ? crc >>> 1 ^ 3988292384 : crc >>> 1;
  }
  crc32Table[i] = crc;
}
function quickValidate(filePath) {
  try {
    if (!fs.existsSync(filePath)) {
      return { valid: false, error: "File not found" };
    }
    const stats = fs.statSync(filePath);
    if (!stats.isFile()) {
      return { valid: false, error: "Path is not a file" };
    }
    if (stats.size === 0) {
      return { valid: false, error: "File is empty" };
    }
    const fd = fs.openSync(filePath, "r");
    fs.closeSync(fd);
    return { valid: true };
  } catch (error) {
    return { valid: false, error: String(error) };
  }
}

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const tempDir = path.join(getTempDir(), "encrypted");
    ensureDir(tempDir);
    cb(null, tempDir);
  },
  filename: (req, file, cb) => {
    const uniqueName = `temp_${Date.now()}_${crypto.randomBytes(8).toString("hex")}`;
    cb(null, uniqueName);
  }
});
const upload = multer({
  storage,
  limits: {
    fileSize: 10 * 1024 * 1024 * 1024
    // 10 GB
  }
});
async function handler(req, res) {
  upload.single("file")(req, res, async (err) => {
    if (err) {
      return res.status(400).json({
        success: false,
        error: "File upload failed",
        message: err.message
      });
    }
    try {
      const { deviceId, backupId, backupType = "full", encryptionKey, metadata } = req.body;
      const file = req.file;
      if (!file) {
        return res.status(400).json({
          success: false,
          error: "No file uploaded"
        });
      }
      if (!deviceId) {
        fs.unlinkSync(file.path);
        return res.status(400).json({
          success: false,
          error: "Device ID is required"
        });
      }
      if (!encryptionKey) {
        fs.unlinkSync(file.path);
        return res.status(400).json({
          success: false,
          error: "Encryption key is required"
        });
      }
      const finalBackupId = backupId || crypto.randomBytes(16).toString("hex");
      const timestamp = Date.now();
      const originalExt = path.extname(file.originalname) || ".backup";
      const encryptedExt = originalExt + ".enc";
      const deviceDir = path.join(getBackupsDir(), deviceId);
      ensureDir(deviceDir);
      const encryptedFilePath = path.join(deviceDir, `${finalBackupId}_${timestamp}${encryptedExt}`);
      const key = Buffer.from(encryptionKey, "base64");
      const encryptionMetadata = await encryptFile(file.path, encryptedFilePath, key);
      fs.unlinkSync(file.path);
      const stats = fs.statSync(encryptedFilePath);
      const sizeInMB = Math.round(stats.size / (1024 * 1024));
      const fileMetadata = await generateFileMetadata(encryptedFilePath);
      const result = await db.insert(backups).values({
        deviceId,
        backupId: finalBackupId,
        backupType,
        status: "completed",
        size: sizeInMB,
        filePath: encryptedFilePath,
        metadata: metadata || null,
        encrypted: true,
        encryptionAlgorithm: encryptionMetadata.algorithm,
        encryptionIv: encryptionMetadata.iv,
        encryptionAuthTag: encryptionMetadata.authTag,
        encryptionSalt: encryptionMetadata.salt || null,
        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 backup = await db.select().from(backups).where(eq(backups.id, insertId)).limit(1);
      res.json({
        success: true,
        backup: backup[0],
        message: "Backup uploaded and encrypted successfully"
      });
    } catch (error) {
      console.error("Encrypted upload error:", error);
      if (req.file && fs.existsSync(req.file.path)) {
        fs.unlinkSync(req.file.path);
      }
      res.status(500).json({
        success: false,
        error: "Failed to upload and encrypt backup",
        message: String(error)
      });
    }
  });
}

export { generateFileMetadata as g, handler as h, quickValidate as q, verifyFileIntegrity as v };
