<?php

namespace App\Dto\Input;

use ApiPlatform\Metadata\ApiProperty;
use App\Dto\Output\OrganizationalUnitOutput;
use App\Dto\Output\SubnetOutput;
use App\Entity\Subnet;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;

final class SubnetInput
{
    #[Assert\NotBlank(message: 'validators.subnet.name.not_blank')]
    #[Groups(['subnet:write'])]
    #[ApiProperty(description: 'The name of the subnet', example: "Subnet 1")]
    public ?string $name = null;

    #[Assert\NotBlank(message: 'validators.subnet.netmask.not_blank')]
    #[Assert\Ip(message: 'validators.subnet.netmask.invalid')]
    #[Groups(['subnet:write'])]
    #[ApiProperty(description: 'The netmask of the subnet', example: "")]
    public ?string $netmask = null;

    #[Assert\NotBlank(message: 'validators.subnet.ip_address.not_blank')]
    #[Assert\Ip(message: 'validators.subnet.ip_address.invalid')]
    #[Groups(['subnet:write'])]
    #[ApiProperty(description: 'The ip address of the subnet', example: "")]
    public ?string $ipAddress = null;

    #[Groups(['subnet:write'])]
    #[ApiProperty(description: 'The next server of the subnet', example: "")]
    public ?string $nextServer = null;

    #[Groups(['subnet:write'])]
    #[ApiProperty(description: 'The router of the subnet', example: "")]
    public ?string $router = null;

    #[Groups(['subnet:write'])]
    #[ApiProperty(description: 'The dns server of the subnet', example: "")]
    public ?string $dns = null;

    #[Groups(['subnet:write'])]
    #[ApiProperty(description: 'The boot file name of the subnet', example: "")]
    public ?string $bootFileName = null;

    /**
     * @var OrganizationalUnitOutput[]
     */
    #[Groups('user:write')]
    #[ApiProperty(readableLink: false,  writableLink: false)]
    public array $organizationalUnits = [];

    public function __construct(?Subnet $subnet = null)
    {
        if (!$subnet) {
            return;
        }

        $this->name = $subnet->getName();
        $this->netmask = $subnet->getNetmask();
        $this->ipAddress = $subnet->getIpAddress();
        $this->router = $subnet->getRouter();
        $this->nextServer = $subnet->getNextServer();
        $this->dns = $subnet->getDns();
        $this->bootFileName = $subnet->getBootFileName();

        if ($subnet->getOrganizationalUnits()) {
            foreach ($subnet->getOrganizationalUnits() as $organizationalUnit) {
                $this->organizationalUnits[] = new OrganizationalUnitOutput($organizationalUnit);
            }
        }
    }

    public function createOrUpdateEntity(?Subnet $subnet = null): Subnet
    {
        if (!$subnet) {
            $subnet = new Subnet();
        }

        $subnet->setName($this->name);
        $subnet->setNetmask($this->netmask);
        $subnet->setIpAddress($this->ipAddress);
        $subnet->setDns($this->dns);
        $subnet->setNextServer($this->nextServer);
        $subnet->setBootFileName($this->bootFileName);
        $subnet->setRouter($this->router);

        foreach ($this->organizationalUnits as $organizationalUnit) {
            $organizationalUnitToAdd[] = $organizationalUnit->getEntity();
        }
        $subnet->setOrganizationalUnits($organizationalUnitToAdd ?? [] );

        return $subnet;
    }
}