<?php

use api\classes\API_devices;

session_start();
require_once "{$_SERVER['DOCUMENT_ROOT']}/api/classes/API_devices.php";

$API_devices = new API_devices();

if ($API_devices->request_method === 'POST') {

    $API_devices->checkPermissions('admin-devices-files', 'RW');

    # when called from the frontend will not be forwarding to a url since when it's called from the frontend it doesn't need a redirection
    $API_devices->return_url = false;

    $device_slugify = isset($_POST['device_slugify']) ? preg_replace('/[^a-zA-Z0-9_-]/', '_', $_POST['device_slugify']) : '';
    $filetype = $_POST['filetype'] ?? '';

    $allowedFiletypes = ['documents' => 'pdf', 'firmware' => 'rom'];
    if (!array_key_exists($filetype, $allowedFiletypes)) {
        $API_devices->apiOutput(400, ['error' => 'Invalid file type']);
    }

    if (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
        $API_devices->apiOutput(400, ['error' => 'No file uploaded or upload error']);
    }

    $filename = basename($_FILES['file']['name']);
    $filename = preg_replace('/[^a-zA-Z0-9_.-]/', '_', $filename);
    $file_extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

    $expectedExtension = $allowedFiletypes[$filetype];
    if ($file_extension !== $expectedExtension) {
        $API_devices->apiOutput(415, ['error' => "Invalid file extension. Expected: $expectedExtension"]);
    }

    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $detectedMime = finfo_file($finfo, $_FILES['file']['tmp_name']);
    finfo_close($finfo);

    $expectedMimeTypes = [
        'pdf' => 'application/pdf',
        'rom' => 'application/octet-stream'
    ];

    if (!str_starts_with($detectedMime, $expectedMimeTypes[$expectedExtension])) {
        $API_devices->apiOutput(415, ['error' => 'Invalid MIME type: ' . $detectedMime]);
    }

    $destination_dir = $_SERVER['DOCUMENT_ROOT'] . '/data/devices/' . $device_slugify . '/' . $filetype;
    if (!is_dir($destination_dir) && !mkdir($destination_dir, 0775, true) && !is_dir($destination_dir)) {
        $API_devices->apiOutput(500, ['error' => 'Failed to create directory']);
    }


    $destination = $destination_dir . '/' . $filename;
    if (file_exists($destination)) {
        $API_devices->apiOutput(409, ['error' => 'File already exists']);
    }

    if (move_uploaded_file($_FILES['file']['tmp_name'], $destination)) {
        chmod($destination, 0644); // Set safe permissions
        $API_devices->apiOutput(200, ['success' => 'File uploaded successfully']);
    } else {
        $API_devices->apiOutput(500, ['error' => 'Failed to move uploaded file']);
    }

} elseif ($API_devices->request_method === 'DELETE') {

    $API_devices->checkPermissions('admin-devices-files', 'RW');

    # when called from the frontend will not be forwarding to a url since when it's called from the frontend it doesn't need a redirection
    $API_devices->return_url = false;

    $relativePath = $_POST['file_name'] ?? '';

    // Ensure it's not empty and doesn't contain null byte or backslashes
    if (empty($relativePath) || str_contains($relativePath, "\0") || str_contains($relativePath, '\\')) {
        http_response_code(400);
        echo json_encode(['status' => 'error', 'message' => 'Invalid path input']);
        exit;
    }

    // Normalize base root
    $root = realpath($_SERVER['DOCUMENT_ROOT'] . '/data/devices');
    if (!$root) {
        http_response_code(500);
        echo json_encode(['status' => 'error', 'message' => 'Invalid devices root']);
        exit;
    }

    // Resolve full path
    $requestedPath = realpath($_SERVER['DOCUMENT_ROOT'] . $relativePath);

    // Validate resolved path
    if (!$requestedPath || !str_starts_with($requestedPath, $root)) {
        http_response_code(403);
        echo json_encode(['status' => 'error', 'message' => 'Access denied']);
        exit;
    }

    // Check if file exists and is a regular file
    if (!is_file($requestedPath)) {
        http_response_code(404);
        echo json_encode(['status' => 'error', 'message' => 'File does not exist']);
        exit;
    }

    // Attempt to delete
    if (unlink($requestedPath)) {
        echo json_encode(['status' => 'success', 'message' => 'File deleted']);
    } else {
        http_response_code(500);
        echo json_encode(['status' => 'error', 'message' => 'Failed to delete file']);
    }

}