<?php
// src/DhcpBundle/Controller/DhcpController.php

namespace App\DhcpBundle\Controller;

use OpenApi\Annotations as OA;
use Psr\Log\LoggerInterface;
use App\DhcpBundle\Service\CurlKeaService;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Exception;


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

    private $curlKeaService;

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

    /**
     * 
     * @OA\Schema(
     *     schema="Subnet",
     *     type="object",
     *     @OA\Property(property="id", type="integer", description="The ID of the subnet"),
     *     @OA\Property(property="subnet", type="string", description="The name of the subnet"),
     *     @OA\Property(property="next-server", type="string", description="The next server in the subnet"),
     *     @OA\Property(property="boot-file-name", type="string", description="The boot file name for the subnet"),
     *     @OA\Property(
     *         property="reservations",
     *         type="array",
     *         @OA\Items(type="object", description="The reservations in the subnet")
     *     )
     * )
     * @OA\Get(
     *     path="/opengnsys3/rest/dhcp/subnets",
     *     @OA\Response(
     *         response=200,
     *         description="Devuelve todas las subredes",
     *         @OA\JsonContent(
     *             type="array",
     *             @OA\Items(ref="#/components/schemas/Subnet")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Error al obtener las subredes",
     *     )
     * )
     * @Route("/opengnsys3/rest/dhcp/subnets", methods={"GET"})
     */
    public function getSubnets(): JsonResponse
    {
        try {
            $response = $this->curlKeaService->executeCurlCommand('config-get');

            if (!$response) {
                $responseError = 'Error: No se pudo acceder al archivo dhcpd.conf';
                return new JsonResponse(['error' => $responseError], 400);
            } else {
                $result_code = $response[0]["result"];
                if ($result_code == 0) {
                    if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
                        $responseError = 'El campo \'subnet4\' no está inicializado';
                        return new JsonResponse(['error' => $responseError], 400);
                    } else {
                        $arrayReservations = $response[0]['arguments']['Dhcp4']['subnet4'];
                        return new JsonResponse($arrayReservations, 200);
                    }
                } else {
                    $responseError =  "Error kea configuration invalid: " . $response[0]["text"];
                    return new JsonResponse(['error' => $responseError], 400);
                }
            }
        } catch (Exception $e) {
            $responseError =  "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
            return new JsonResponse(['error' => $responseError], 400);
        }
    }

    /**
     * @OA\Post(
     *     path="/opengnsys3/rest/dhcp/subnets",
     *     summary="Add a new DHCP subnet",
     *     @OA\RequestBody(
     *         description="JSON payload",
     *         required=true,
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="subnetId", type="integer", example=2),
     *             @OA\Property(property="mask", type="string", example="255.255.255.0"),
     *             @OA\Property(property="address", type="string", example="192.168.1.0"),
     *             @OA\Property(property="nextServer", type="string", example="192.168.1.1"),
     *             @OA\Property(property="bootFileName", type="string", example="pxelinux.0")
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Subnet added successfully",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="success", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Error occurred",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="error", type="string")
     *         )
     *     )
     * )
     * @Route("/opengnsys3/rest/dhcp/subnets", methods={"POST"})
     */
    public function addDhcpSubnet(Request $request): JsonResponse
    {
        try {
            $input = json_decode($request->getContent());
            $subnetId = (int) htmlspecialchars($input->subnetId);
            $mask = htmlspecialchars($input->mask);
            $address = htmlspecialchars($input->address);
            $nextServer = htmlspecialchars($input->nextServer);
            $bootFileName = htmlspecialchars($input->bootFileName);
        } catch (Exception $e) {
            $response["message"] = $e->getMessage();
            return new JsonResponse(['error' => $response], 400);
        }

        try {
            $response = $this->curlKeaService->executeCurlCommand('config-get');
            $subnetName = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask);
            $newSubnet = [
                "id" => $subnetId,
                "subnet" => $subnetName,
                "next-server" => $nextServer,
                "boot-file-name" => $bootFileName,
                "reservations" => []
            ];

            if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
                $response[0]['arguments']['Dhcp4']['subnet4'] = [];
            }

            $exists = array_reduce($response[0]['arguments']['Dhcp4']['subnet4'], function ($exists, $subnetElement) use ($subnetName, $subnetId) {
                return $exists || ($subnetElement['subnet'] === $subnetName) || ($subnetElement['id'] === $subnetId);;
            });

            if ($exists) {
                $responseError =  "Error: La subred el subnet '$subnetName' ya existe en las subredes";
                return new JsonResponse(['error' => $responseError], 400);
            } else {
                $response[0]['arguments']['Dhcp4']['subnet4'][] = $newSubnet;
                $array_encoded = json_encode($response[0]['arguments']);
                $configurationParsed = str_replace('\\', '', $array_encoded);
                $configuration = json_decode($configurationParsed);
                $responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);

                if ($responseTest[0]["result"] == 0) {
                    $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
                    if ($responseSet == false || $responseSet[0]["result"] != 0) {
                        $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
                        return new JsonResponse(['error' => $responseError], 400);
                    } else {
                        $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
                        if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
                            $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
                            return new JsonResponse(['error' => $responseError], 400);
                        } else {
                            $responseSuccess =  "Configuración cargada correctamente";
                            return new JsonResponse(['success' => $responseSuccess], 200);
                        }
                    }
                } else {
                    $responseError =  "Error kea configuration invalid: " . $responseTest[0]["text"];
                    return new JsonResponse(['error' => $responseError], 400);
                }
            }
        } catch (Exception $e) {
            $responseError =  "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
            return new JsonResponse(['error' => $responseError], 400);
        }
    }



    /**
     * @Route("/opengnsys3/rest/dhcp/subnets/{subnetId}", methods={"DELETE"})
     * @OA\Delete(
     *     path="/opengnsys3/rest/dhcp/subnets/{subnetId}",
     *     summary="Delete a DHCP subnet",
     *     @OA\Parameter(
     *         name="subnetId",
     *         in="path",
     *         description="ID of the subnet to delete",
     *         required=true,
     *         @OA\Schema(
     *             type="integer"
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Subnet deleted successfully",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="success", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Error occurred",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="error", type="string")
     *         )
     *     )
     * )
     * @Route("/opengnsys3/rest/dhcp/subnets/{subnetId}", methods={"DELETE"})
     */
    public function deleteDhcpSubnet(Request $request): JsonResponse
    {
        $subnetId = (int) $request->get('subnetId');

        try {
            $response = $this->curlKeaService->executeCurlCommand('config-get');

            if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
                $responseError =  "Error: No hay subredes definidas";
                return new JsonResponse(['error' => $responseError], 400);
            }

            $subnetIndex = array_search($subnetId, array_column($response[0]['arguments']['Dhcp4']['subnet4'], 'id'));

            if ($subnetIndex === false) {
                $responseError =  "Error: La subred con el id '$subnetId' no existe";
                return new JsonResponse(['error' => $responseError], 400);
            } else {
                unset($response[0]['arguments']['Dhcp4']['subnet4'][$subnetIndex]);
                $response[0]['arguments']['Dhcp4']['subnet4'] = array_values($response[0]['arguments']['Dhcp4']['subnet4']);
                $array_encoded = json_encode($response[0]['arguments']);
                $configurationParsed = str_replace('\\', '', $array_encoded);
                $configuration = json_decode($configurationParsed);
                $responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);

                if ($responseTest[0]["result"] == 0) {
                    $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
                    if ($responseSet == false || $responseSet[0]["result"] != 0) {
                        $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
                        return new JsonResponse(['error' => $responseError], 400);
                    } else {
                        $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
                        if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
                            $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
                            return new JsonResponse(['error' => $responseError], 400);
                        } else {
                            $responseSuccess =  "Subred eliminada correctamente";
                            return new JsonResponse(['success' => $responseSuccess], 200);
                        }
                    }
                } else {
                    $responseError =  "Error kea configuration invalid: " . $responseTest[0]["text"];
                    return new JsonResponse(['error' => $responseError], 400);
                }
            }
        } catch (Exception $e) {
            $responseError =  "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
            return new JsonResponse(['error' => $responseError], 400);
        }
    }


    /**
     * @Route("/opengnsys3/rest/dhcp/subnets/{subnetId}", methods={"PUT"})
     * @OA\Put(
     *     path="/opengnsys3/rest/dhcp/subnets/{subnetId}",
     *     summary="Modify a DHCP subnet",
     *     @OA\Parameter(
     *         name="subnetId",
     *         in="path",
     *         description="ID of the subnet to modify",
     *         required=true,
     *         @OA\Schema(
     *             type="integer"
     *         )
     *     ),
     *     @OA\RequestBody(
     *         description="Data to modify the subnet",
     *         required=true,
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="mask", type="string"),
     *             @OA\Property(property="address", type="string"),
     *             @OA\Property(property="nextServer", type="string"),
     *             @OA\Property(property="bootFileName", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Subnet modified successfully",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="success", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Error occurred",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="error", type="string")
     *         )
     *     )
     * )
     * @Route("/opengnsys3/rest/dhcp/subnets/{subnetId}", methods={"PUT"})
     */
    public function modifyDhcpSubnet(Request $request): JsonResponse
    {
        $subnetId = (int) $request->get('subnetId');

        try {
            $input = json_decode($request->getContent());
            $mask = htmlspecialchars($input->mask);
            $address = htmlspecialchars($input->address);
            $nextServer = htmlspecialchars($input->nextServer);
            $bootFileName = htmlspecialchars($input->bootFileName);
        } catch (Exception $e) {
            $response["message"] = $e->getMessage();
            return new JsonResponse(['error' => $response], 400);
        }

        try {
            $response = $this->curlKeaService->executeCurlCommand('config-get');
            $subnetName = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask);

            if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
                $responseError =  "Error: No hay subredes definidas";
                return new JsonResponse(['error' => $responseError], 400);
            }

            $subnetIndex = array_search($subnetId, array_column($response[0]['arguments']['Dhcp4']['subnet4'], 'id'));

            if ($subnetIndex === false) {
                $responseError =  "Error: La subred con el id '$subnetId' no existe";
                return new JsonResponse(['error' => $responseError], 400);
            } else {
                $response[0]['arguments']['Dhcp4']['subnet4'][$subnetIndex] = [
                    "id" => $subnetId,
                    "subnet" => $subnetName,
                    "next-server" => $nextServer,
                    "boot-file-name" => $bootFileName,
                    "reservations" => []
                ];
                $array_encoded = json_encode($response[0]['arguments']);
                $configurationParsed = str_replace('\\', '', $array_encoded);
                $configuration = json_decode($configurationParsed);
                $responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);

                if ($responseTest[0]["result"] == 0) {
                    $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
                    if ($responseSet == false || $responseSet[0]["result"] != 0) {
                        $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
                        return new JsonResponse(['error' => $responseError], 400);
                    } else {
                        $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
                        if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
                            $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
                            return new JsonResponse(['error' => $responseError], 400);
                        } else {
                            $responseSuccess =  "Subred modificada correctamente";
                            return new JsonResponse(['success' => $responseSuccess], 200);
                        }
                    }
                } else {
                    $responseError =  "Error kea configuration invalid: " . $responseTest[0]["text"];
                    return new JsonResponse(['error' => $responseError], 400);
                }
            }
        } catch (Exception $e) {
            $responseError =  "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
            return new JsonResponse(['error' => $responseError], 400);
        }
    }


    /**
     * @OA\Schema(
     *     schema="Host",
     *     type="object",
     *     @OA\Property(property="host", type="string", example="pc11"),
     *     @OA\Property(property="macAddress", type="string", example="56:6f:c7:4f:00:4f"),
     *     @OA\Property(property="address", type="string", example="172.30.4.11")
     * )
     * @OA\Get(
     *     path="/opengnsys3/rest/dhcp/subnets/{subnetId}/hosts",
     *     summary="Get all hosts in a subnet",
     *     @OA\Parameter(
     *         name="subnetId",
     *         in="path",
     *         description="The ID of the subnet",
     *         required=true,
     *         @OA\Schema(type="integer")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="List of hosts in the subnet",
     *         @OA\JsonContent(
     *             type="array",
     *             @OA\Items(ref="#/components/schemas/Host")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Error occurred",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="error", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=500,
     *         description="Server error",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="error", type="string")
     *         )
     *     )
     * )
     * @Route("/opengnsys3/rest/dhcp/subnets/{subnetId}/hosts", methods={"GET"})
     */
    public function getHosts($subnetId): JsonResponse
    {
        try {
            $response = $this->curlKeaService->executeCurlCommand('config-get');

            if (!$response) {
                $responseError = 'Error: No se pudo acceder al archivo dhcpd.conf';
                return new JsonResponse(['error' => $responseError], 400);
            } else {
                $result_code = $response[0]["result"];
                if ($result_code == 0) {
                    if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
                        $responseError = 'El campo \'subnet4\' no está inicializado';
                        return new JsonResponse(['error' => $responseError], 400);
                    } else {
                        $subnets = $response[0]['arguments']['Dhcp4']['subnet4'];
                        foreach ($subnets as $subnet) {
                            if ($subnet['id'] == $subnetId) {
                                return new JsonResponse($subnet['reservations'], 200);
                            }
                        }
                        $responseError = 'Error: La subred con el id \'' . $subnetId . '\' no existe.';
                        return new JsonResponse(['error' => $responseError], 400);
                    }
                } else {
                    $responseError =  "Error kea configuration invalid: " . $response[0]["text"];
                    return new JsonResponse(['error' => $responseError], 400);
                }
            }
        } catch (Exception $e) {
            $responseError =  "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
            return new JsonResponse(['error' => $responseError], 400);
        }
    }


    /**
     * @Route("/opengnsys3/rest/dhcp/subnets/{subnetId}/hosts", methods={"POST"})
     * @OA\Post(
     *     path="/opengnsys3/rest/dhcp/subnets/{subnetId}/hosts",
     *     summary="Add a DHCP host to a subnet",
     *     @OA\Parameter(
     *         name="subnetId",
     *         in="path",
     *         description="ID of the subnet to add the host to",
     *         required=true,
     *         @OA\Schema(
     *             type="integer"
     *         )
     *     ),
     *     @OA\RequestBody(
     *         description="Data for the new host",
     *         required=true,
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="host", type="string", example="pc11"),
     *             @OA\Property(property="macAddress", type="string", example="56:6f:c7:4f:00:4f"),
     *             @OA\Property(property="address", type="string", example="172.30.4.11")
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Host added successfully",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="success", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Error occurred",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="error", type="string")
     *         )
     *     )
     * )
     * @Route("/opengnsys3/rest/dhcp/subnets/{subnetId}/hosts", methods={"POST"})
     */
    public function addDhcpHost(Request $request): JsonResponse
    {
        $subnetId = (int) $request->get('subnetId');
        try {
            $input = json_decode($request->getContent());
            $host = htmlspecialchars($input->host);
            $macAddress = htmlspecialchars($input->macAddress);
            $address = htmlspecialchars($input->address);
        } catch (Exception $e) {
            $response["message"] = $e->getMessage();
            return new JsonResponse(['error' => $response], 400);
        }

        try {
            $response = $this->curlKeaService->executeCurlCommand('config-get');
            $newHost = [
                "hostname" => $host,
                "hw-address" => $macAddress,
                "ip-address" => $address
            ];

            $subnetFound = false;
            foreach ($response[0]['arguments']['Dhcp4']['subnet4'] as &$subnet) {
                if ($subnet['id'] == $subnetId) {
                    $subnetFound = true;
                    if (!isset($subnet['reservations'])) {
                        $subnet['reservations'] = [];
                    }

                    $exists = array_reduce($subnet['reservations'], function ($exists, $reservation) use ($host) {
                        return $exists || ($reservation['hostname'] === $host);
                    });

                    if ($exists) {
                        $responseError =  "Error: El host con el hostname '$host' ya existe en las reservaciones.";
                        return new JsonResponse(['error' => $responseError], 400);
                    } else {
                        $subnet['reservations'][] = $newHost;
                        break;
                    }
                }
            }

            if (!$subnetFound) {
                $responseError =  "Error: No se encontró la subnet con id '$subnetId'.";
                return new JsonResponse(['error' => $responseError], 400);
            }

            $array_encoded = json_encode($response[0]['arguments']);
            $configurationParsed = str_replace('\\', '', $array_encoded);
            $configuration = json_decode($configurationParsed);
            $responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);

            if ($responseTest[0]["result"] == 0) {
                $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
                if ($responseSet == false || $responseSet[0]["result"] != 0) {
                    $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
                    return new JsonResponse(['error' => $responseError], 400);
                } else {
                    $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
                    if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
                        $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
                        return new JsonResponse(['error' => $responseError], 400);
                    } else {
                        $responseSuccess =  "Configuración cargada correctamente";
                        return new JsonResponse(['success' => $responseSuccess], 200);
                    }
                }
            } else {
                $responseError =  "Error kea configuration invalid: " . $responseTest[0]["text"];
                return new JsonResponse(['error' => $responseError], 400);
            }
        } catch (Exception $e) {
            $responseError =  "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
            return new JsonResponse(['error' => $responseError], 400);
        }
    }

    /**
     * @OA\Delete(
     *     path="/opengnsys3/rest/dhcp/subnets/{subnetId}/hosts",
     *     summary="Delete a DHCP host from a specific subnet",
     *     @OA\Parameter(
     *         name="subnetId",
     *         in="path",
     *         description="The ID of the subnet",
     *         required=true,
     *         @OA\Schema(type="integer")
     *     ),
     *     @OA\RequestBody(
     *         description="Data for the host to delete",
     *         required=true,
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="host", type="string", example="pc11")
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Host deleted successfully",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="success", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Error occurred",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="error", type="string")
     *         )
     *     )
     * )
     * @Route("/opengnsys3/rest/dhcp/subnets/{subnetId}/hosts", methods={"DELETE"})
     */
    public function deleteDhcpHost(Request $request, $subnetId): JsonResponse
    {
        try {
            $input = json_decode($request->getContent());
            $host = htmlspecialchars($input->host);
        } catch (Exception $e) {
            $response["message"] = $e->getMessage();
            return new JsonResponse(['error' => $response], 400);
        }

        try {
            $response = $this->curlKeaService->executeCurlCommand('config-get');
            $subnetFound = false;

            foreach ($response[0]['arguments']['Dhcp4']['subnet4'] as &$subnet) {
                if ($subnet['id'] == $subnetId) {
                    $subnetFound = true;
                    if (!isset($subnet['reservations'])) {
                        $subnet['reservations'] = [];
                    }

                    foreach ($subnet['reservations'] as $key => $reservation) {
                        if (isset($reservation['hostname']) && $reservation['hostname'] === $host) {
                            unset($subnet['reservations'][$key]);
                            $subnet['reservations'] = array_values($subnet['reservations']);
                            break;
                        }
                    }
                }
            }

            if ($subnetFound) {
                $array_encoded = json_encode($response[0]['arguments']);
                $configurationParsed = str_replace('\\', '', $array_encoded);
                $configuration = json_decode($configurationParsed);

                $responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
                if ($responseTest[0]["result"] == 0) {
                    $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
                    if ($responseSet == false || $responseSet[0]["result"] != 0) {
                        $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
                        return new JsonResponse(['error' => $responseError], 400);
                    } else {
                        $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
                        if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
                            $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
                            return new JsonResponse(['error' => $responseError], 400);
                        } else {
                            $responseSuccess =  "Configuración cargada correctamente";
                            return new JsonResponse(['success' => $responseSuccess], 200);
                        }
                    }
                } else {
                    $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseTest[0]["text"];
                    return new JsonResponse(['error' => $responseError], 400);
                }
            } else {
                $responseError =  "Error: El host con el hostname '$host' no existe en las reservaciones.";
                return new JsonResponse(['error' => $responseError], 400);
            }
        } catch (Exception $e) {
            $responseError =  "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
            return new JsonResponse(['error' => $responseError], 400);
        }
    }


    /**
     * @OA\Put(
     *     path="/opengnsys3/rest/dhcp/subnets/{subnetId}/hosts",
     *     summary="Update a DHCP host",
     *     @OA\Parameter(
     *         name="subnetId",
     *         in="path",
     *         description="The ID of the subnet",
     *         required=true,
     *         @OA\Schema(type="integer")
     *     ),
     *     @OA\RequestBody(
     *         description="Data for the host to update",
     *         required=true,
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="host", type="string", example="pc11"),
     *             @OA\Property(property="oldMacAddress", type="string", example="56:6f:c7:4f:00:4f"),
     *             @OA\Property(property="oldAddress", type="string", example="192.168.1.11"),
     *             @OA\Property(property="macAddress", type="string", example="56:6f:c7:4f:01:01"),
     *             @OA\Property(property="address", type="string", example="192.168.1.11")
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Host updated successfully",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="success", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Error occurred",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="error", type="string")
     *         )
     *     )
     * )
     *
     * @Route("/opengnsys3/rest/dhcp/subnets/{subnetId}/hosts", methods={"PUT"})
     */
    public function updateDhcpHost(Request $request, $subnetId): JsonResponse
    {

        try {
            $input = json_decode($request->getContent());
            $host = htmlspecialchars($input->host);
            $oldMacAddress = htmlspecialchars($input->oldMacAddress);
            $oldAddress = htmlspecialchars($input->oldAddress);
            $macAddress = htmlspecialchars($input->macAddress);
            $address = htmlspecialchars($input->address);
        } catch (Exception $e) {
            $response["message"] = $e->getMessage();
            return new JsonResponse(['error' => $response], 400);
        }

        try {
            $response = $this->curlKeaService->executeCurlCommand('config-get');
            $subnetFound = false;
            $hostFound = false;

            foreach ($response[0]['arguments']['Dhcp4']['subnet4'] as &$subnet) {
                if ($subnet['id'] == $subnetId) {
                    $this->logger->info('FOUND SUBNET');
                    $subnetFound = true;
                    if (!isset($subnet['reservations'])) {
                        $subnet['reservations'] = [];
                    }

                    foreach ($subnet['reservations'] as &$reservation) {
                        $this->logger->info('LOOKING FOR  HOST');
                        if ($reservation['hw-address'] == $oldMacAddress && $reservation['ip-address'] == $oldAddress) {
                            $this->logger->info('FOUND HOST');
                            $hostFound = true;
                            $reservation['hw-address'] = $macAddress;
                            $reservation['ip-address'] = $address;
                            $reservation['hostname'] = $host;
                            break;
                        }
                    }
                }
            }

            if ($subnetFound && $hostFound) {
                $this->logger->info('UPDATING HOST');
                $array_encoded = json_encode($response[0]['arguments']);
                $configurationParsed = str_replace('\\', '', $array_encoded);
                $configuration = json_decode($configurationParsed);

                $responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
                if ($responseTest[0]["result"] == 0) {
                    $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
                    if ($responseSet == false || $responseSet[0]["result"] != 0) {
                        $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
                        return new JsonResponse(['error' => $responseError], 400);
                    } else {
                        $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
                        if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
                            $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
                            return new JsonResponse(['error' => $responseError], 400);
                        } else {
                            $responseSuccess =  "Configuración cargada correctamente";
                            return new JsonResponse(['success' => $responseSuccess], 200);
                        }
                    }
                } else {
                    $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseTest[0]["text"];
                    return new JsonResponse(['error' => $responseError], 400);
                }
            } elseif (!$subnetFound) {
                $responseError =  "Error: La subred con el id '$subnetId' no existe.";
                return new JsonResponse(['error' => $responseError], 400);
            } elseif (!$hostFound) {
                $responseError =  "Error: La IP " . $oldAddress . " y la MAC " . $oldMacAddress . " no existe en las reservaciones.";
                return new JsonResponse(['error' => $responseError], 400);
            }
        } catch (Exception $e) {
            $responseError =  "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
            return new JsonResponse(['error' => $responseError], 400);
        }
    }

    /**
     * @Route("/opengnsys3/rest/dhcp/backup", methods={"POST"})
     */
    public function restoreDhcpConfiguration(): JsonResponse
    {
        $backup_dir = '/opt/opengnsys/etc/kea/backup';
        try {
            $backup_files = glob($backup_dir . '/*.conf');
            if (empty($backup_files)) {
                $response =  "No se encontraron archivos de backup";
                return new JsonResponse(['error' => $response], 400);
            } else {
                usort($backup_files, function ($a, $b) {
                    return filemtime($b) - filemtime($a);
                });
                $backup_file = reset($backup_files);
                $config = file_get_contents($backup_file);
                $configuration = json_decode($config);
                $test_command = 'config-test';
                $test_output = $this->curlKeaService->executeCurlCommand($test_command, $configuration);
                if ($test_output == false || $test_output[0]["result"] != 0) {
                    $responseError =  "Error al comprobar la configuración de Kea: " . $test_output[0]["text"];
                    return new JsonResponse(['error' => $responseError], 400);
                } else {
                    $set_command = 'config-set';
                    $set_output = $this->curlKeaService->executeCurlCommand($set_command, $configuration, false);
                    if ($set_output == false || $set_output[0]["result"] != 0) {
                        $responseError =  "Error al guardar la última configuración de Kea: " . $set_output[0]["text"];
                        return new JsonResponse(['error' => $responseError], 400);                        
                    } else {
                        unlink($backup_file);
                        $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
                        if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
                            $responseError =  "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
                            return new JsonResponse(['error' => $responseError], 400);
                        } else {
                            $responseSuccess =  "Configuración cargada correctamente";
                            return new JsonResponse(['success' => $responseSuccess], 200);
                        }
                    }
                }
            }
        } catch (Exception $e) {
            $responseError =  "Error al restaurar la configuración: " . $e->getMessage();
            return new JsonResponse(['error' => $responseError], 400);
        }
    }


}
