<?php

namespace App\Dto\Input;

use ApiPlatform\Metadata\ApiProperty;
use App\Dto\Output\ClientOutput;
use App\Dto\Output\ImageImageRepositoryOutput;
use App\Dto\Output\ImageOutput;
use App\Dto\Output\ImageRepositoryOutput;
use App\Dto\Output\OrganizationalUnitOutput;
use App\Dto\Output\PartitionOutput;
use App\Dto\Output\RemoteCalendarRuleOutput;
use App\Dto\Output\SoftwareProfileOutput;
use App\Entity\Image;
use App\Entity\ImageImageRepository;
use App\Entity\OrganizationalUnit;
use App\Entity\Partition;
use App\Model\ImageStatus;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;

final class ImageInput
{
    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The name of the image', example: "Image 1")]
    public ?string $name = null;

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

    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The optional selected image')]
    public ?ImageOutput $selectedImage = null;

    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The software profile of the image')]
    public ?SoftwareProfileOutput $softwareProfile = null;

    /**
     * @var ImageRepositoryOutput[]
     */
    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The image repository of the image')]
    public ?array $imageRepositories = [];

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

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

    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The parent of the image')]
    public ?self $parent = null;

    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The parent of the image')]
    public ?int $version = null;

    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The remote pc of the image')]
    public ?bool $remotePc = false;

    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The global property of the image')]
    public ?bool $isGlobal = false;

    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The queue property of the image')]
    public bool $queue = false;

    #[Groups(['image:write'])]
    #[ApiProperty(description: 'The name of the Git repository to use for this image', example: "mi-repositorio")]
    public ?string $gitRepository = null;

    public function __construct(?Image $image = null)
    {
        if (!$image) {
            return;
        }

        $this->name = $image->getName();
        $this->type = $image->getType();
        $this->remotePc = $image->isRemotePc();
        $this->isGlobal = $image->isGlobal();
        $this->version = $image->getVersion();

        if ($image->getSoftwareProfile()) {
            $this->softwareProfile = new SoftwareProfileOutput($image->getSoftwareProfile());
        }

        if ($image->getClient()) {
            $this->client = new ClientOutput($image->getClient());
        }

        if ($image->getImageImageRepositories()) {
            $this->imageRepositories = array_map(fn($imageImageRepository) => new ImageImageRepositoryOutput($imageImageRepository), $image->getImageImageRepositories()->toArray());
        }

        if ($image->getParent()) {
            $this->parent = new self($image->getParent());
        }
    }

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

        $image->setName($this->name);
        $image->setType($this->type);

        if ($this->softwareProfile) {
            $image->setSoftwareProfile($this->softwareProfile->getEntity());
        }

        if ($this->client) {
            $image->setClient($this->client->getEntity());
        }

        if ($this->imageRepositories) {
            foreach ($this->imageRepositories as $imageRepository) {
                $aux = new ImageImageRepository();
                $aux->setImage($image);
                $aux->setRepository($imageRepository->getEntity());
                $aux->setStatus('');
                if (!$image->containsImageImageRepository($aux)) {
                    $image->addImageImageRepository($aux);
                }
            }
        }

        $image->setRemotePc($this->remotePc);
        $image->setIsGlobal($this->isGlobal);

        $partitionInfo = [];

        if ($this->partition) {
            /** @var Partition $partition */
            $partition = $this->partition->getEntity();
            $partitionInfo["numDisk"] = $partition->getDiskNumber();
            $partitionInfo["numPartition"] = $partition->getPartitionNumber();
            $partitionInfo["partitionCode"] = $partition->getPartitionCode();
            $partitionInfo["filesystem"] = $partition->getFilesystem();
            $partitionInfo["osName"] = $partition->getOperativeSystem()?->getName();
            $image->setPartitionInfo(json_encode($partitionInfo));
        }

        return $image;
    }
}