<?php
// src/OgBootBundle/Controller/OgBootController.php

namespace App\OgBootBundle\Controller;
use OpenApi\Annotations as OA;
use Psr\Log\LoggerInterface;
use App\OgBootBundle\Service\CurlRequestService;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Exception;


class OgBootController
{
    private $logger;
    /**
     * @OA\Info(title="Ogboot API", version="1.0")
     */

    private $curlRequestService;

    public function __construct(CurlRequestService $curlRequestService, LoggerInterface $logger)
    {
        $this->curlRequestService = $curlRequestService;
        $this->logger = $logger;
    }

/*Tabla de Contenido
Obtener configuración de ogboot - GET /ogboot/config x
Obtener datos de rendimiento - GET /ogboot/status x
Mostrar información de todos los clientes ogLive instalados - GET /ogboot/oglives x 
Mostrar información de un cliente ogLive instalado - GET /ogboot/oglives/{Index|Dir} x
Mostrar información del cliente ogLive predeterminado - GET /ogboot/oglives/default x
Cambiar ogLive predeterminado - POST /ogboot/oglives/default/{Index} x 
Instalar nuevo cliente ogLive desde imagen descargada - POST /ogboot/oglive/{Index/iso} ----
Desinstalar cliente ogLive y eliminar imagen - DELETE /ogboot/oglives/{Index/iso} -------
Regenerar archivo de información de los ogLive - PUT /ogboot/oglives
Mostrar menú de descarga de imagen de ogLive - GET /ogboot/images/download X 

/////////////////////////////////////////////

Obtener todos los archivos de arranque - GET /ogboot/pxes
Obtener archivo de arranque - GET /ogboot/clients/pxes/{mac}
Crear archivo de arranque - POST /ogboot/pxes
Eliminar archivo de arranque - DELETE /ogboot/clients/pxes
Obtener todas las plantillas - GET /ogboot/pxe-templates
Obtener contenido de la plantilla - GET /ogboot/pxe-templates/{nombre}
Crear plantilla - POST /ogboot/pxe-templates
Regenerar plantilla - PUT /ogboot/pxe-templates
*/

    /**
    * @Route("/ogboot/help", name="help", methods={"GET"})
    */
    public function help(): Response
    {

        # $result = $this->curlRequestService->common_request(OG_REST_CMD_POWEROFF, POST, [OG_REST_PARAM_CLIENTS => $ips]);
        $result = $this->curlRequestService->callOgLive("help");

        if ($result) {
            return new Response($result, Response::HTTP_OK);
        } else {
            return new Response('Failed', Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

/**
 * @Route("/ogboot/v1/config", name="getConfig", methods={"GET"})
 * @OA\Get(
 *     path="/ogboot/v1/config",
 *     summary="Get ogboot configuration",
 *     @OA\Response(
 *         response=200,
 *         description="Configuration retrieved successfully",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="disk_usage", type="object",
 *                 @OA\Property(property="total", type="string"),
 *                 @OA\Property(property="used", type="string"),
 *                 @OA\Property(property="available", type="string"),
 *                 @OA\Property(property="percentage", type="string")
 *             ),
 *             @OA\Property(property="default_oglive", type="string"),
 *             @OA\Property(property="installed_oglives", type="array", @OA\Items(type="string"))
 *         )
 *     )
 * )
 */
public function getConfig(): Response
{
    // Call oglivecli to get disk usage
    $diskUsageResult = $this->curlRequestService->callOgLive("disk_usage");

    if (is_array($diskUsageResult) && isset($diskUsageResult['success']) && $diskUsageResult['success'] === false) {
        return new JsonResponse(['error' => 'Failed to retrieve disk usage', 'details' => $diskUsageResult['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
    }

    // Call oglivecli to get installed oglives and default oglives
    $ogLiveConfigResult = $this->curlRequestService->callOgLive("list_installed_oglives");

    if (is_array($ogLiveConfigResult) && isset($ogLiveConfigResult['success']) && $ogLiveConfigResult['success'] === false) {
        return new JsonResponse(['error' => 'Failed to retrieve ogLive configuration', 'details' => $ogLiveConfigResult['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
    }

    // Call oglivecli to get installed oglives and default oglives
    $servicesStatusResult = $this->curlRequestService->callOgLive("check_services_status");

    if (is_array($servicesStatusResult) && isset($servicesStatusResult['success']) && $servicesStatusResult['success'] === false) {
        return new JsonResponse(['error' => 'Failed to retrieve services status', 'details' => $servicesStatusResult['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
    }

    $response = [
        'disk_usage' => $diskUsageResult,
        'default_oglive' => $ogLiveConfigResult['default_oglive'],
        'installed_oglives' => $ogLiveConfigResult['installed_ogLives'],
        'services_status' => $servicesStatusResult
    ];

    return new JsonResponse($response, Response::HTTP_OK);
}



/**
 * @Route("/ogboot/v1/oglives/isos", name="getDownloadMenu", methods={"GET"})
 * @OA\Get(
 *     path="/ogboot/v1/oglives/isos",
 *     summary="Get ogLive downloads menu",
 *     @OA\Response(
 *         response=200,
 *         description="Isos retrieved successfully",
 *         @OA\JsonContent(
 *             type="array",
 *             @OA\Items(type="object",
 *                 @OA\Property(property="id", type="integer"),
 *                 @OA\Property(property="filename", type="string"),
 *                 @OA\Property(property="installed", type="boolean"),
 *                 @OA\Property(property="compatible", type="boolean")
 *             )
 *         )
 *     ),
 *     @OA\Response(
 *         response=500,
 *         description="Failed to retrieve isos",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="error", type="string"),
 *             @OA\Property(property="details", type="string")
 *         )
 *     )
 * )
 */
public function getDownloadMenu(): Response
{
    $downloadsOutput = $this->curlRequestService->callOgLive("download");

    if (is_array($downloadsOutput) && isset($downloadsOutput['success']) && $downloadsOutput['success'] === false) {
        return new JsonResponse(['error' => 'Failed to retrieve downloads', 'details' => $downloadsOutput['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
    }

    return new JsonResponse($downloadsOutput, Response::HTTP_OK);
}

/**
 * @Route("/ogboot/v1/oglives", name="getOglives", methods={"GET"})
 * @OA\Get(
 *     path="/ogboot/v1/oglives",
 *     summary="Get list of all installed ogLive clients",
 *     @OA\Response(
 *         response=200,
 *         description="Successful operation",
 *         @OA\JsonContent(
 *             type="array",
 *             @OA\Items(
 *                 type="object",
 *                 @OA\Property(
 *                     property="id",
 *                     type="string",
 *                     description="Unique identifier for the ogLive client, generated from linuxISO.sum",
 *                     example="9e49a085ba74f97a81bdf9b3d0785094"
 *                 ),
 *                 @OA\Property(
 *                     property="distribution",
 *                     type="string",
 *                     description="Distribution name of the installed ogLive client"
 *                 ),
 *                 @OA\Property(
 *                     property="kernel",
 *                     type="string",
 *                     description="Kernel version of the installed ogLive client"
 *                 ),
 *                 @OA\Property(
 *                     property="architecture",
 *                     type="string",
 *                     description="Architecture of the installed ogLive client"
 *                 ),
 *                 @OA\Property(
 *                     property="revision",
 *                     type="string",
 *                     description="Revision of the installed ogLive client"
 *                 ),
 *                 @OA\Property(
 *                     property="directory",
 *                     type="string",
 *                     description="Directory name of the installed ogLive client"
 *                 ),
 *                 @OA\Property(
 *                     property="iso",
 *                     type="string",
 *                     description="ISO file name of the installed ogLive client"
 *                 )
 *             )
 *         )
 *     ),
 *     @OA\Response(
 *         response=404,
 *         description="No ogLive clients found"
 *     )
 * )
 */
public function getOglives(): Response
{
    $directoryPath = '/opt/ogboot/tftpboot/';
    $pattern = '/^ogLive-([\w.-]+)-r(\d+)$/';

    $ogLives = [];
    
    if ($handle = opendir($directoryPath)) {
        error_log("Opened directory: $directoryPath");

        while (false !== ($entry = readdir($handle))) {
            error_log("Processing entry: $entry");

            if ($entry != "." && $entry != ".." && is_dir($directoryPath . $entry)) {
                if (preg_match($pattern, $entry, $matches)) {
                    error_log("Entry matches pattern: $entry");

                    // Evitar directorios .old
                    if (substr($entry, -4) === '.old') {
                        error_log("Ignoring old directory: $entry");
                        continue;
                    }

                    // Extraer detalles
                    $distribution = $matches[1];
                    $revision = $matches[2];
                    $directory = $entry;
                    $ogLivePath = $directoryPath . $entry;

                    // Obtener el ID del archivo linuxISO.sum
                    $sumFile = $ogLivePath . '/linuxISO.sum';
                    $id = '';
                    if (file_exists($sumFile)) {
                        $id = trim(file_get_contents($sumFile));
                    }

                    // Obtener el nombre del archivo ISO
                    $iso = '';
                    $oldInfoFile = $ogLivePath . '/OLDINFOFILE';
                    if (file_exists($oldInfoFile)) {
                        $iso = trim(file($oldInfoFile, FILE_USE_INCLUDE_PATH | FILE_IGNORE_NEW_LINES)[0]);
                    }

                    // Obtener la versión del kernel
                    $kernelFile = $ogLivePath . '/ogvmlinuz';
                    $kernel = '';
                    if (file_exists($kernelFile)) {
                        $fileOutput = shell_exec("file -bkr $kernelFile");
                        if (preg_match('/Linux kernel.*version (\d+\.\d+\.\d+)/', $fileOutput, $kernelMatches)) {
                            $kernel = $kernelMatches[1];
                        }
                    }

                    // Asumir arquitectura como 'amd64'; puedes refinar esto si se necesita más lógica
                    $architecture = 'amd64';

                    // Construir el objeto
                    $ogLives[] = [
                        'id' => $id,
                        'distribution' => $distribution,
                        'kernel' => $kernel,
                        'architecture' => $architecture,
                        'revision' => $revision,
                        'directory' => $directory,
                        'iso' => $iso
                    ];
                } else {
                    error_log("Entry does not match pattern: $entry");
                }
            } else {
                error_log("Entry is not a directory: $directoryPath$entry");
            }
        }

        closedir($handle);
        error_log("Closed directory: $directoryPath");
    }

    if (!empty($ogLives)) {
        error_log("Returning ogLives data");
        return new JsonResponse($ogLives, Response::HTTP_OK);
    } else {
        error_log("No ogLive clients found");
        return new JsonResponse(['error' => 'No ogLive clients found'], Response::HTTP_NOT_FOUND);
    }
}

/**
 * @Route("/ogboot/v1/oglives/default", name="getOgliveDefault", methods={"GET"})
 * @OA\Get(
 *     path="/ogboot/v1/oglives/default",
 *     summary="Get information of the default ogLive client",
 *     @OA\Response(
 *         response=200,
 *         description="Successful operation",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(
 *                 property="distribution",
 *                 type="string",
 *                 description="Distribution name of the default ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="kernel",
 *                 type="string",
 *                 description="Kernel version of the default ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="architecture",
 *                 type="string",
 *                 description="Architecture of the default ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="revision",
 *                 type="string",
 *                 description="Revision of the default ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="directory",
 *                 type="string",
 *                 description="Directory name of the default ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="iso",
 *                 type="string",
 *                 description="ISO file name of the default ogLive client"
 *             )
 *         )
 *     ),
 *     @OA\Response(
 *         response=500,
 *         description="Failed to retrieve information of the default ogLive client"
 *     )
 * )
 */
public function getOgliveDefault(Request $request): Response
{
    $result = $this->curlRequestService->callOgLive("get_default");

    if (is_array($result) && isset($result['error'])) {
        return new JsonResponse(['error' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
    }

    return new JsonResponse($result, Response::HTTP_OK);
}

/**
 * @Route("/ogboot/v1/oglives/{checksum}", name="getOglive", methods={"GET"})
 * @OA\Get(
 *     path="/ogboot/v1/oglives/{checksum}",
 *     summary="Get information of an installed ogLive client",
 *     @OA\Parameter(
 *         name="checksum",
 *         in="path",
 *         description="Checksum of the installed ogLive client",
 *         required=true,
 *         @OA\Schema(
 *             type="string",
 *             example="9e49a085ba74f97a81bdf9b3d0785094"
 *         )
 *     ),
 *     @OA\Response(
 *         response=200,
 *         description="Successful operation",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(
 *                 property="distribution",
 *                 type="string",
 *                 description="Distribution name of the installed ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="kernel",
 *                 type="string",
 *                 description="Kernel version of the installed ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="architecture",
 *                 type="string",
 *                 description="Architecture of the installed ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="revision",
 *                 type="string",
 *                 description="Revision of the installed ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="directory",
 *                 type="string",
 *                 description="Directory name of the installed ogLive client"
 *             ),
 *             @OA\Property(
 *                 property="iso",
 *                 type="string",
 *                 description="ISO file name of the installed ogLive client"
 *             )
 *         )
 *     ),
 *     @OA\Response(
 *         response=404,
 *         description="ogLive client not found"
 *     )
 * )
 */
public function getOglive(string $checksum): Response
{
    $result = $this->curlRequestService->callOgLive("get_info " . escapeshellarg($checksum));

    if (is_array($result) && isset($result['error'])) {
        return new JsonResponse(['error' => $result['error']], Response::HTTP_NOT_FOUND);
    }

    return new JsonResponse($result, Response::HTTP_OK);
}







/**
 * @Route("/ogboot/v1/oglives/default", name="setOgliveDefault", methods={"POST"})
 * @OA\Post(
 *     path="/ogboot/v1/oglives/default",
 *     summary="Set default ogLive client",
 *     @OA\RequestBody(
 *         required=true,
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(
 *                 property="checksum",
 *                 type="string",
 *                 example="9e49a085ba74f97a81bdf9b3d0785094",
 *                 description="Checksum of the ogLive client to set as default"
 *             )
 *         )
 *     ),
 *     @OA\Response(
 *         response=200,
 *         description="ogLive client set as default successfully",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="message", type="string")
 *         )
 *     ),
 *     @OA\Response(
 *         response=404,
 *         description="ogLive client not found"
 *     ),
 *     @OA\Response(
 *         response=500,
 *         description="Failed to set default ogLive client"
 *     )
 * )
 */
public function setOgliveDefault(Request $request): Response
{
    $data = json_decode($request->getContent(), true);

    if (!isset($data['checksum'])) {
        return new JsonResponse(['error' => 'Invalid input data'], Response::HTTP_BAD_REQUEST);
    }

    $checksum = $data['checksum'];

    // Establecer el ogLive como predeterminado utilizando el checksum proporcionado
    $result = $this->curlRequestService->callOgLive("set_default " . escapeshellarg($checksum));

    if (is_array($result) && isset($result['error'])) {
        return new JsonResponse(['error' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
    }

    return new JsonResponse(['message' => 'ogLive client set as default successfully'], Response::HTTP_OK);
}






/**
 * @Route("/ogboot/v1/oglives/install", name="installOglive", methods={"POST"})
 * @OA\Post(
 *     path="/ogboot/v1/oglives/install",
 *     summary="Install an ogLive client",
 *     @OA\RequestBody(
 *         required=true,
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(
 *                 property="isoname",
 *                 type="string",
 *                 example="ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f.iso",
 *                 description="Name of the ogLive ISO to install"
 *             )
 *         )
 *     ),
 *     @OA\Response(
 *         response=200,
 *         description="ogLive client installed successfully",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="message", type="string"),
 *             @OA\Property(property="details", type="object")
 *         )
 *     ),
 *     @OA\Response(
 *         response=400,
 *         description="Invalid input data"
 *     ),
 *     @OA\Response(
 *         response=500,
 *         description="Failed to install ogLive client",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="error", type="string"),
 *             @OA\Property(property="details", type="string")
 *         )
 *     )
 * )
 */
public function installOglive(Request $request): Response
{
    $data = json_decode($request->getContent(), true);

    if (!isset($data['isoname'])) {
        return new JsonResponse(['error' => 'Invalid input data'], Response::HTTP_BAD_REQUEST);
    }

    $isoname = $data['isoname'];
    $result = $this->curlRequestService->callOgLive("download " . escapeshellarg($isoname));

    if (is_array($result) && isset($result['success']) && $result['success'] === false) {
        return new JsonResponse(['error' => 'Failed to install ogLive client', 'details' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
    }

    return new JsonResponse(['message' => 'ogLive client installed successfully', 'details' => $result], Response::HTTP_OK);
}

    
    
/**
 * @Route("/ogboot/v1/oglives/{checksum}", name="uninstallOglive", methods={"DELETE"})
 * @OA\Delete(
 *     path="/ogboot/v1/oglives/{checksum}",
 *     summary="Uninstall an ogLive client",
 *     @OA\Parameter(
 *         name="checksum",
 *         in="path",
 *         description="Checksum of the ogLive client to uninstall",
 *         required=true,
 *         @OA\Schema(type="string", example="9e49a085ba74f97a81bdf9b3d0785094")
 *     ),
 *     @OA\Response(
 *         response=200,
 *         description="ogLive client uninstalled successfully",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="message", type="string"),
 *             @OA\Property(property="details", type="string")
 *         )
 *     ),
 *     @OA\Response(
 *         response=404,
 *         description="ogLive client not found"
 *     ),
 *     @OA\Response(
 *         response=500,
 *         description="Failed to uninstall ogLive client",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="error", type="string")
 *         )
 *     )
 * )
 */
public function uninstallOglive(string $checksum): Response
{
    // Llamada al servicio para desinstalar el cliente ogLive
    error_log("Calling curlRequestService with checksum: $checksum");
    $result = $this->curlRequestService->callOgLive("uninstall " . escapeshellarg($checksum));

    // Verificar la respuesta del servicio
    error_log("Service call result: " . print_r($result, true));

    if (is_array($result) && isset($result['error'])) {
        // Error encontrado en la respuesta
        error_log("Error found in response: " . $result['error']);
        return new JsonResponse(['error' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
    } elseif (is_array($result) && isset($result['message'])) {
        // Respuesta exitosa
        error_log("Success response: " . print_r($result, true));
        return new JsonResponse([
            'message' => $result['message'],
            'details' => $result['details'] ?? ''
        ], Response::HTTP_OK);
    } else {
        // Manejar el caso en que no se recibió una respuesta válida del servicio
        error_log("Failed to uninstall ogLive client, empty result from service");
        return new JsonResponse(['error' => 'Failed to uninstall ogLive client'], Response::HTTP_INTERNAL_SERVER_ERROR);
    }
}




/**
 * @Route("/ogboot/v1/pxes", name="get_boot_files", methods={"GET"})
 * @OA\Get(
 *     path="/ogboot/v1/pxes",
 *     summary="Get all PXE boot files",
 *     @OA\Response(
 *         response=200,
 *         description="Successful operation",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(
 *                 property="boot_files",
 *                 type="array",
 *                 @OA\Items(
 *                     type="string",
 *                     description="Boot file"
 *                 )
 *             )
 *         )
 *     ),
 *     @OA\Response(
 *         response=500,
 *         description="Failed to retrieve boot files"
 *     )
 * )
 */
public function getBootFiles(): JsonResponse
{

    $directory = '/opt/ogboot/tftpboot/ipxe_scripts';


    $files = scandir($directory);


    $bootFiles = array_filter($files, function ($file) use ($directory) {
        return !is_dir($directory . '/' . $file) && strpos($file, '01-') === 0;
    });

    $response = [
        'boot_files' => array_values($bootFiles)
    ];

    return new JsonResponse($response, Response::HTTP_OK);
}

/**
 * @Route("/ogboot/v1/pxes/{mac}", name="ogboot_get_boot_file_with_params", methods={"GET"})
 * @OA\Get(
 *     path="/ogboot/v1/pxes/{mac}",
 *     summary="Get boot file with parameters",
 *     @OA\Parameter(
 *         name="mac",
 *         in="path",
 *         description="MAC address",
 *         required=true,
 *         @OA\Schema(type="string", example="00:50:56:22:11:12")
 *     ),
 *     @OA\Response(
 *         response=200,
 *         description="Successful operation",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="template_name", type="string", description="Template name", example="pxe"),
 *             @OA\Property(property="mac", type="string", description="MAC address", example="00:50:56:22:11:12"),
 *             @OA\Property(property="lang", type="string", description="Language", example="es_ES.UTF-8"),
 *             @OA\Property(property="ip", type="string", description="IP address", example="192.168.2.11"),
 *             @OA\Property(property="server_ip", type="string", description="Server IP address", example="192.168.2.1"),
 *             @OA\Property(property="router", type="string", description="Router", example="192.168.2.1"),
 *             @OA\Property(property="netmask", type="string", description="Netmask", example="255.255.255.0"),
 *             @OA\Property(property="computer_name", type="string", description="Computer name", example="pc11"),
 *             @OA\Property(property="netiface", type="string", description="Network interface", example="eth0"),
 *             @OA\Property(property="group", type="string", description="Group", example="Aula_virtual"),
 *             @OA\Property(property="ogrepo", type="string", description="Repository IP", example="192.168.2.1"),
 *             @OA\Property(property="oglive", type="string", description="Live server IP", example="192.168.2.1"),
 *             @OA\Property(property="oglog", type="string", description="Log server IP", example="192.168.2.1"),
 *             @OA\Property(property="ogshare", type="string", description="Share server IP", example="192.168.2.1"),
 *             @OA\Property(property="oglivedir", type="string", description="Live directory", example="ogLive"),
 *             @OA\Property(property="ogprof", type="string", description="Is professor", example="false"),
 *             @OA\Property(property="hardprofile", type="string", description="Hardware profile", example=""),
 *             @OA\Property(property="ogntp", type="string", description="NTP server", example=""),
 *             @OA\Property(property="ogdns", type="string", description="DNS server", example=""),
 *             @OA\Property(property="ogproxy", type="string", description="Proxy server", example=""),
 *             @OA\Property(property="ogunit", type="string", description="Unit directory", example=""),
 *             @OA\Property(property="resolution", type="string", description="Screen resolution", example="788")
 *         )
 *     ),
 *     @OA\Response(
 *         response=500,
 *         description="Failed to retrieve boot file"
 *     )
 * )
 */
public function getBootFile(string $mac): Response
{
    // Ruta donde están alojados los archivos de arranque
    $directory = '/opt/ogboot/tftpboot/ipxe_scripts';

    // Genera el nombre del archivo basado en la dirección MAC
    $fileName = "01-" . $mac;

    $filePath = "$directory/$fileName";

    if (!file_exists($filePath)) {
        return new JsonResponse(['error' => 'No se encontró ningún archivo de arranque con la dirección MAC especificada'], Response::HTTP_NOT_FOUND);
    }

    $content = file_get_contents($filePath);
    $templateName = '';
    $contentLines = explode("\n", $content);
    foreach ($contentLines as $line) {
        if (strpos($line, '#template_name:') !== false) {
            $templateName = trim(str_replace('#template_name:', '', $line));
            break;
        }
    }

    // Extraer los parámetros del contenido del archivo iPXE
    preg_match('/set kernelargs (.*)/', $content, $matches);
    if (isset($matches[1])) {
        $kernelargs = $matches[1];
        parse_str(str_replace(' ', '&', $kernelargs), $params);

        $result = [
            'template_name' => $templateName,
            'mac' => $mac,
            'lang' => $params['LANG'] ?? '',
            'ip' => explode(':', $params['ip'])[0] ?? '',
            'server_ip' => explode(':', $params['ip'])[1] ?? '',
            'router' => explode(':', $params['ip'])[2] ?? '',
            'netmask' => explode(':', $params['ip'])[3] ?? '',
            'computer_name' => explode(':', $params['ip'])[4] ?? '',
            'netiface' => explode(':', $params['ip'])[5] ?? '',
            'group' => $params['group'] ?? '',
            'ogrepo' => $params['ogrepo'] ?? '',
            'oglive' => $params['oglive'] ?? '',
            'oglog' => $params['oglog'] ?? '',
            'ogshare' => $params['ogshare'] ?? '',
            'oglivedir' => $params['oglivedir'] ?? '',
            'ogprof' => $params['ogprof'] ?? '',
            'hardprofile' => $params['hardprofile'] ?? '',
            'ogntp' => $params['ogntp'] ?? '',
            'ogdns' => $params['ogdns'] ?? '',
            'ogproxy' => $params['ogproxy'] ?? '',
            'ogunit' => $params['ogunit'] ?? '',
            'resolution' => $params['vga'] ?? '',
        ];

        return new JsonResponse($result, Response::HTTP_OK);
    }

    return new JsonResponse(['error' => 'Failed to parse kernel arguments from the boot file'], Response::HTTP_INTERNAL_SERVER_ERROR);
}

    /**
     * @Route("/ogboot/v1/pxes", name="create_boot_file", methods={"POST"})
     * @OA\Post(
     *     path="/ogboot/v1/pxes",
     *     summary="Create a new PXE boot file",
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="template_name", type="string", description="Template name", example="pxe"),
     *             @OA\Property(property="mac", type="string", description="MAC address", example="00:50:56:22:11:12"),
     *             @OA\Property(property="lang", type="string", description="Language", example="es_ES.UTF-8"),
     *             @OA\Property(property="ip", type="string", description="IP address", example="192.168.2.11"),
     *             @OA\Property(property="server_ip", type="string", description="Server IP address", example="192.168.2.1"),
     *             @OA\Property(property="router", type="string", description="Router", example="192.168.2.1"),
     *             @OA\Property(property="netmask", type="string", description="Netmask", example="255.255.255.0"),
     *             @OA\Property(property="computer_name", type="string", description="Computer name", example="pc11"),
     *             @OA\Property(property="netiface", type="string", description="Network interface", example="eth0"),
     *             @OA\Property(property="group", type="string", description="Group", example="Aula_virtual"),
     *             @OA\Property(property="ogrepo", type="string", description="Repository IP", example="192.168.2.1"),
     *             @OA\Property(property="oglive", type="string", description="Live server IP", example="192.168.2.1"),
     *             @OA\Property(property="oglog", type="string", description="Log server IP", example="192.168.2.1"),
     *             @OA\Property(property="ogshare", type="string", description="Share server IP", example="192.168.2.1"),
     *             @OA\Property(property="oglivedir", type="string", description="Live directory", example="ogLive"),
     *             @OA\Property(property="ogprof", type="string", description="Is professor", example="false"),
     *             @OA\Property(property="hardprofile", type="string", description="Hardware profile", example=""),
     *             @OA\Property(property="ogntp", type="string", description="NTP server", example=""),
     *             @OA\Property(property="ogdns", type="string", description="DNS server", example=""),
     *             @OA\Property(property="ogproxy", type="string", description="Proxy server", example=""),
     *             @OA\Property(property="ogunit", type="string", description="Unit directory", example=""),
     *             @OA\Property(property="resolution", type="string", description="Screen resolution", example="788")
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="PXE boot file created successfully",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="message", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Invalid input"
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="Template not found"
     *     ),
     *     @OA\Response(
     *         response=500,
     *         description="Internal server error"
     *     )
     * )
     */
    public function createBootFile(Request $request): JsonResponse
    {
        $data = json_decode($request->getContent(), true);

        $templateName = $data['template_name'] ?? null;
        $mac = $data['mac'] ?? null;
        $serverIp = $data['server_ip'] ?? null;
        $ogLiveDir = $data['oglivedir'] ?? 'ogLive';

        if (!$templateName || !$mac || !$serverIp) {
            return new JsonResponse(['error' => 'Invalid input'], Response::HTTP_BAD_REQUEST);
        }

        $parameters = [
            'LANG' => $data['lang'] ?? 'es_ES.UTF-8',
            'ip' => $data['ip'] ?? '',
            'router' => $data['router'] ?? '',
            'netmask' => $data['netmask'] ?? '',
            'computer_name' => $data['computer_name'] ?? '',
            'netiface' => $data['netiface'] ?? '',
            'group' => $data['group'] ?? '',
            'ogrepo' => $data['ogrepo'] ?? '',
            'oglive' => $data['oglive'] ?? $serverIp,
            'oglog' => $data['oglog'] ?? $serverIp,
            'ogshare' => $data['ogshare'] ?? $serverIp,
            'oglivedir' => $data['oglivedir'] ?? '',
            'ogprof' => $data['ogprof'] ?? 'false',
            'hardprofile' => $data['hardprofile'] ?? '',
            'ogntp' => $data['ogntp'] ?? '',
            'ogdns' => $data['ogdns'] ?? '',
            'ogproxy' => $data['ogproxy'] ?? '',
            'ogunit' => $data['ogunit'] ?? '',
            'resolution' => $data['resolution'] ?? '788'
        ];

        $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates';
        $templatePath = $templateDir . '/' . $templateName;

        if (!file_exists($templatePath)) {
            return new JsonResponse(['error' => 'Template not found'], Response::HTTP_NOT_FOUND);
        }

        $templateContent = file_get_contents($templatePath);
        if ($templateContent === false) {
            return new JsonResponse(['error' => 'Failed to read template'], Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        $kernelArgs = 'ro boot=oginit quiet splash irqpoll acpi=on og2nd=sqfs ogprotocol=smb ogactiveadmin=true ogdebug=true ogtmpfs=15 ' .
            'oglivedir=' . $parameters['oglivedir'] . ' ' .
            'LANG=' . $parameters['LANG'] . ' ' .
            'ip=' . $parameters['ip'] . ':' . $serverIp . ':' . $parameters['router'] . ':' . $parameters['netmask'] . ':' . $parameters['computer_name'] . ':' . $parameters['netiface'] . ':none ' .
            'group=' . str_replace(' ', '_', trim($parameters['group'])) . ' ' .
            'ogrepo=' . $parameters['ogrepo'] . ' ' .
            'oglive=' . $serverIp . ' ' .
            'oglog=' . $serverIp . ' ' .
            'ogshare=' . $serverIp . ' ' .
            'ogprof=' . ($parameters['ogprof'] === 'true' ? 'true' : 'false') . ' ' .
            (!empty($parameters['hardprofile']) ? 'hardprofile=' . str_replace(' ', '_', trim($parameters['hardprofile'])) . ' ' : '') .
            (!empty($parameters['ogntp']) ? 'ogntp=' . $parameters['ogntp'] . ' ' : '') .
            (!empty($parameters['ogdns']) ? 'ogdns=' . $parameters['ogdns'] . ' ' : '') .
            (!empty($parameters['ogproxy']) ? 'ogproxy=' . $parameters['ogproxy'] . ' ' : '') .
            (!empty($parameters['ogunit']) ? 'ogunit=' . $parameters['ogunit'] . ' ' : '') .
            (is_numeric($parameters['resolution']) && $parameters['resolution'] <= 999 ? 'vga=' . $parameters['resolution'] :
                (strpos($parameters['resolution'], ':') !== false ? 'video=' . $parameters['resolution'] : ' ' . $parameters['resolution']));


        $pxeContent = str_replace(['__INFOHOST__', '__SERVERIP__', '__OGLIVE__'], [$kernelArgs, $serverIp, $ogLiveDir], $templateContent);


        $pxeFileName = '01-' . $mac; 

        $pxeFilePath = '/opt/ogboot/tftpboot/ipxe_scripts/' . $pxeFileName;

        if (file_put_contents($pxeFilePath, $pxeContent) === false) {
            return new JsonResponse(['error' => 'Failed to create PXE boot file'], Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        return new JsonResponse(['message' => 'PXE boot file created successfully'], Response::HTTP_OK);
    }

/**
 * @Route("/ogboot/v1/pxes/{mac}", name="ogboot_delete_boot_file", methods={"DELETE"})
 * @OA\Delete(
 *     path="/ogboot/v1/pxes/{mac}",
 *     summary="Eliminar archivo de arranque",
 *     description="Elimina un archivo de arranque específico utilizando su dirección MAC.",
 *     @OA\Parameter(
 *         name="mac",
 *         in="path",
 *         description="La dirección MAC del cliente cuyo archivo de arranque se desea eliminar",
 *         required=true,
 *         @OA\Schema(type="string", example="00:11:22:33:44:55")
 *     ),
 *     @OA\Response(
 *         response=200,
 *         description="El archivo de arranque se eliminó correctamente",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="message", type="string", example="El archivo de arranque se eliminó correctamente")
 *         )
 *     ),
 *     @OA\Response(
 *         response=404,
 *         description="No se encontró ningún archivo de arranque con la dirección MAC especificada",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="error", type="string", example="No se encontró ningún archivo de arranque con la dirección MAC especificada")
 *         )
 *     ),
 *     @OA\Response(
 *         response=500,
 *         description="Error al eliminar el archivo de arranque",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="error", type="string", example="Error al eliminar el archivo de arranque")
 *         )
 *     )
 * )
 */
    public function deleteBootFile(string $mac): Response
    {
        $directory = '/opt/ogboot/tftpboot/ipxe_scripts';

        $fileName = "01-" . $mac;

        $filePath = "$directory/$fileName";

        if (!file_exists($filePath)) {
            
            return new JsonResponse(['error' => 'No se encontró ningún archivo de arranque con la dirección MAC especificada'], Response::HTTP_NOT_FOUND);
        }

        if (!unlink($filePath)) {
            
            return new JsonResponse(['error' => 'Error al eliminar el archivo de arranque'], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
        return new JsonResponse(['message' => 'El archivo de arranque se eliminó correctamente'], Response::HTTP_OK);
    }
    

    /**
     * @Route("/ogboot/v1/pxe-templates", methods={"GET"})
     * @OA\Get(
     *     path="/ogboot/v1/pxe-templates",
     *     summary="Obtener todas las plantillas PXE",
     *     description="Obtiene una lista de todas las plantillas de arranque PXE disponibles.",
     *     @OA\Response(
     *         response=200,
     *         description="Lista de plantillas de arranque PXE",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(
     *                 property="templates",
     *                 type="array",
     *                 @OA\Items(type="string", example="mi_plantilla.ipxe")
     *             )
     *         )
     *     ),
     *     @OA\Response(
     *         response=500,
     *         description="Error interno del servidor"
     *     )
     * )
     */
    public function getAllTemplates(): JsonResponse
    {
        $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates';

        // Verificar si el directorio existe
        if (!is_dir($templateDir)) {
            return new JsonResponse(['error' => 'Directorio de plantillas no encontrado'], Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        // Obtener la lista de archivos en el directorio
        $files = scandir($templateDir);

        // Filtrar los archivos válidos (excluir directorios y archivos ocultos)
        $templates = array_filter($files, function ($file) use ($templateDir) {
            return !in_array($file, ['.', '..']) && !is_dir($templateDir . '/' . $file);
        });

        return new JsonResponse(['templates' => array_values($templates)], Response::HTTP_OK);
    }

    /**
     * @Route("/ogboot/v1/pxe-templates/{templateName}", name="get_template", methods={"GET"})
     * @OA\Get(
     *     path="/ogboot/v1/pxe-templates/{templateName}",
     *     summary="Obtener contenido de una plantilla PXE",
     *     description="Obtiene el contenido de una plantilla de arranque PXE específica por su nombre.",
     *     @OA\Parameter(
     *         name="templateName",
     *         in="path",
     *         required=true,
     *         description="Nombre de la plantilla PXE",
     *         @OA\Schema(type="string", example="mi_plantilla.ipxe")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Contenido de la plantilla de arranque PXE",
     *         @OA\MediaType(
     *             mediaType="text/plain",
     *             @OA\Schema(type="string", example="#!ipxe\nset timeout 0\nset timeout-style hidden\n\nset ISODIR ogLive\nset default 0\nset kernelargs INFOHOST\nkernel tftp://SERVERIP/ogLive/ogvmlinuz ${kernelargs}\ninitrd tftp://SERVERIP/ogLive/oginitrd.img\nboot")
     *         )
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="Plantilla no encontrada"
     *     ),
     *     @OA\Response(
     *         response=500,
     *         description="Error interno del servidor"
     *     )
     * )
     */
    public function getTemplate(string $templateName): Response
    {
        $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates';
        $filePath = "$templateDir/$templateName";

        if (!file_exists($filePath)) {
            return new Response(null, Response::HTTP_NOT_FOUND);
        }

        $content = file_get_contents($filePath);
        if ($content === false) {
            return new Response('Error al leer la plantilla', Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        return new Response($content, Response::HTTP_OK, ['Content-Type' => 'text/plain']);
    }

    /**
     * @Route("/ogboot/v1/pxe-templates", methods={"POST"})
     * 
     * @OA\Post(
     *     path="/ogboot/v1/pxe-templates",
     *     summary="Crear Plantilla",
     *     description="Crea una nueva plantilla de arranque utilizando los datos proporcionados.",
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="name_template", type="string", example="pxe"),
     *             @OA\Property(property="content_template", type="string", example="#!ipxe\nset timeout 0\nset timeout-style hidden\n\nset ISODIR ogLive\nset default 0\nset kernelargs INFOHOST\nkernel tftp://SERVERIP/ogLive/ogvmlinuz ${kernelargs}\ninitrd tftp://SERVERIP/ogLive/oginitrd.img\nboot")
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="La plantilla de arranque se creó exitosamente.",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="message", type="string", example="Plantilla creada exitosamente."),
     *             @OA\Property(property="template", type="string", example="#!ipxe\nset timeout 0\nset timeout-style hidden\n\nset ISODIR ogLive\nset default 0\nset kernelargs INFOHOST\nkernel tftp://SERVERIP/ogLive/ogvmlinuz ${kernelargs}\ninitrd tftp://SERVERIP/ogLive/oginitrd.img\nboot")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="La solicitud no pudo ser procesada debido a un error en los datos proporcionados en el cuerpo de la solicitud."
     *     ),
     *     @OA\Response(
     *         response=500,
     *         description="Ocurrió un error al crear la plantilla de arranque."
     *     )
     * )
     */
    public function createTemplate(Request $request)
    {
        $data = json_decode($request->getContent(), true);

        if (!isset($data['name_template']) || !isset($data['content_template'])) {
            return new Response('La solicitud no pudo ser procesada debido a un error en los datos proporcionados en el cuerpo de la solicitud.', 400);
        }

        $nameTemplate = $data['name_template'];
        $contentTemplate = $data['content_template'];
        $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates';
        if (!preg_match('/^[a-zA-Z0-9._-]+$/', $nameTemplate)) {
            return new Response('Nombre de la plantilla no válido.', 400);
        }

        $filePath = $templateDir . '/' . $nameTemplate;
        $contentTemplate = str_replace("\\n", "\n", $contentTemplate);
        try {
            file_put_contents($filePath, $contentTemplate);
        } catch (\Exception $e) {
            return new Response('Ocurrió un error al crear la plantilla de arranque.', 500);
        }

        return new Response(json_encode([
            'message' => 'Plantilla creada exitosamente.',
            'template' => $contentTemplate
        ]), 200, ['Content-Type' => 'application/json']);
    }



   /**
     * @Route("/ogboot/v1/pxe-templates/{name}", methods={"DELETE"})
     * 
     * @OA\Delete(
     *     path="/ogboot/v1/pxe-templates/{name}",
     *     summary="Eliminar Plantilla",
     *     description="Elimina una plantilla de arranque específica utilizando su nombre.",
     *     @OA\Parameter(
     *         name="name",
     *         in="path",
     *         required=true,
     *         description="El nombre de la plantilla de arranque que se desea eliminar.",
     *         @OA\Schema(type="string")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="La plantilla de arranque se eliminó correctamente.",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="message", type="string", example="Plantilla eliminada correctamente.")
     *         )
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="No se encontró ninguna plantilla de arranque con el nombre especificado."
     *     ),
     *     @OA\Response(
     *         response=500,
     *         description="Ocurrió un error al eliminar la plantilla de arranque."
     *     )
     * )
     */
    public function deleteTemplate($name)
    {
        $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates';
        $filePath = $templateDir . '/' . $name;

        if (!file_exists($filePath)) {
            return new Response('No se encontró ninguna plantilla de arranque con el nombre especificado.', 404);
        }

        try {
            unlink($filePath);
        } catch (\Exception $e) {
            return new Response('Ocurrió un error al eliminar la plantilla de arranque.', 500);
        }

        return new Response(json_encode([
            'message' => 'Plantilla eliminada correctamente.'
        ]), 200, ['Content-Type' => 'application/json']);
    }


}
