<?php

namespace App\Dto\Input;

use ApiPlatform\Metadata\ApiProperty;
use App\Dto\Output\ImageOutput;
use App\Dto\Output\OperativeSystemOutput;
use App\Entity\Partition;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;

final class PartitionInput
{
    #[Groups(['partition:write', 'client:write'])]
    public ?UuidInterface $uuid = null;

    #[Groups(['partition:write'])]
    public ?bool $removed = null;

    #[Groups(['partition:write', 'client:write'])]
    public ?bool $format = null;

    #[Groups(['partition:write', 'client:write'])]
    #[ApiProperty(description: 'The disk number of the partition', example: 1)]
    public ?int $diskNumber = null;

    #[Groups(['partition:write', 'client:write'])]
    #[ApiProperty(description: 'The number of the partition', example: 1)]
    public ?int $partitionNumber = null;

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

    #[Assert\NotNull()]
    #[Groups(['partition:write', 'client:write'])]
    #[ApiProperty(description: 'The size of the partition', example: 100)]
    public ?float $size = null;

    #[Groups(['partition:write', 'client:write'])]
    #[ApiProperty(description: 'The cache content of the partition', example: "cache content")]
    public ?string $cacheContent = null;

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

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

    #[Groups(['partition:write', 'client:write'])]
    #[ApiProperty(description: 'The operative system name of the partition', example: "Ubuntu")]
    public ?OperativeSystemOutput $operativeSystem = null;

    #[Groups(['partition:write', 'client:write'])]
    #[ApiProperty(description: 'The memory usage of the partition', example: 100)]
    public ?int $memoryUsage = null;

    #[Groups(['partition:write', 'client:write'])]
    #[ApiProperty(description: 'The image of the partition')]
    public ?ImageOutput $image = null;

    public function __construct(?Partition $partition = null)
    {
        if (!$partition) {
            return;
        }

        $this->diskNumber = $partition->getDiskNumber();
        $this->partitionNumber = $partition->getPartitionNumber();
        $this->partitionCode = $partition->getPartitionCode();
        $this->size = $partition->getSize();
        $this->cacheContent = $partition->getCacheContent();
        $this->filesystem = $partition->getFilesystem();

        if ($partition->getOperativeSystem()) {
            $this->operativeSystem = new OperativeSystemOutput($partition->getOperativeSystem());
        }

        $this->memoryUsage = $partition->getMemoryUsage();

        if ($partition->getImage()) {
            $this->image = new ImageOutput($partition->getImage());
        }
    }

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

        $partition->setDiskNumber($this->diskNumber);
        $partition->setPartitionNumber($this->partitionNumber);
        $partition->setPartitionCode($this->partitionCode);
        $partition->setSize($this->size * 1024);
        $partition->setCacheContent($this->cacheContent);
        $partition->setFilesystem($this->filesystem);

        if ($this->operativeSystem) {
            $partition->setOperativeSystem($this->operativeSystem->getEntity());
        }
        $partition->setMemoryUsage($this->memoryUsage * 100);

        if ($this->image) {
            $partition->setImage($this->image->getEntity());
        }

        return $partition;
    }
}
