<?php

declare(strict_types=1);

namespace Webapp\FileManagement\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Column;
use Shared\Authentication\Entity\Site;
use Shared\TransferSync\Entity\StatusDataEntry;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Webapp\FileManagement\ApiOperation\CreateParsingJobOperation;
use Webapp\FileManagement\Entity\Base\UserLinkedFileJob;
use Webapp\FileManagement\Service\ProjectFileInterface;

/**
 * @ApiResource(
 *     normalizationContext={
 *         "groups"={"request_file_read", "user_linked_file_job_read"}
 *     },
 *     denormalizationContext={
 *         "groups"={"request_file_write"}
 *     },
 *     collectionOperations={
 *         "post"={
 *             "controller"=CreateParsingJobOperation::class,
 *             "deserialize"=false,
 *             "access_control"="is_granted('ROLE_USER')",
 *             "validation_groups"={"Default", "media_object_create"},
 *             "openapi_context"={
 *                 "requestBody"={
 *                     "content"={
 *                         "multipart/form-data"={
 *                             "schema"={
 *                                 "type"="object",
 *                                 "properties"={
 *                                     "file"={
 *                                         "type"="string",
 *                                         "format"="binary"
 *                                     },
 *                                 }
 *                             }
 *                         }
 *                     }
 *                 }
 *             }
 *         },
 *         "get" = {}
 *     },
 *     itemOperations={
 *         "get"={ "is_granted('ROLE_USER') && security"="object.getUser() == user" },
 *         "put"={ "is_granted('ROLE_USER') && security"="object.getUser() == user" },
 *         "delete" = { "security"= "is_granted('ROLE_USER') && object.getUser() == user" }
 *     },
 *     attributes={
 *          "order"={"id":"DESC"},
 *          "security"="is_granted('ROLE_USER')"
 *     }
 * )
 *
 * @ORM\Entity
 *
 * @ORM\Table(name="parsing_job", schema="webapp")
 *
 * @psalm-type ParsingJobType = self::TYPE_*
 */
class ParsingJob extends UserLinkedFileJob implements ProjectFileInterface
{
    public const TYPE_EXPERIMENT = 'experiment';
    public const TYPE_EXPERIMENT_CSV = 'experiment_csv';
    public const TYPE_PROTOCOL_CSV = 'protocol_csv';
    public const TYPE_DATA_ENTRY_CSV = 'data_entry_csv';
    public const TYPE_PATH_BASE_CSV = 'path_base_csv';
    public const TYPE_PLATFORM = 'platform';
    public const TYPE_PROJECT_DATA_ZIP = 'project_data_zip';
    public const TYPE_VARIABLE_COLLECTION = 'variable_collection';

    /**
     * @Assert\NotNull(groups={"media_object_create"})
     *
     * @Vich\UploadableField(mapping="project_file", fileNameProperty="filePath")
     */
    protected $file;

    /**
     * @ORM\Column(type="string")
     */
    private string $objectType = '';

    /**
     * @ORM\ManyToOne(targetEntity="Shared\Authentication\Entity\Site", inversedBy="parsingJobs")
     *
     * @ORM\JoinColumn(nullable=false)
     */
    private Site $site;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private ?string $csvBindings = null;

    /**
     * @ORM\ManyToOne(targetEntity="Shared\TransferSync\Entity\StatusDataEntry")
     *
     * @ORM\JoinColumn(nullable=true)
     */
    private ?StatusDataEntry $statusDataEntry = null;

    /**
     * @Groups({"user_linked_file_job_read"})
     *
     * @ORM\Column(type="json", nullable=true)
     */
    private array $errors = [];

    /**
     * @Groups({"user_linked_file_job_read"})
     *
     * @Column(type="string", nullable=true)
     */
    private ?string $objectIri = null;

    /**
     * @psalm-mutation-free
     */
    public function getObjectType(): string
    {
        return $this->objectType;
    }

    /**
     * @return $this
     */
    public function setObjectType(string $objectType): self
    {
        $this->objectType = $objectType;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getSite(): Site
    {
        return $this->site;
    }

    /**
     * @return $this
     */
    public function setSite(Site $site): self
    {
        $this->site = $site;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getObjectIri(): ?string
    {
        return $this->objectIri;
    }

    /**
     * @return $this
     */
    public function setObjectIri(?string $objectIri): self
    {
        $this->objectIri = $objectIri;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getCsvBindings(): ?string
    {
        return $this->csvBindings;
    }

    /**
     * @return $this
     */
    public function setCsvBindings(?string $csvBindings): self
    {
        $this->csvBindings = $csvBindings;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getErrors(): array
    {
        return $this->errors;
    }

    /**
     * @return $this
     */
    public function setErrors(array $errors): self
    {
        $this->errors = $errors;

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getStatusDataEntry(): ?StatusDataEntry
    {
        return $this->statusDataEntry;
    }

    /**
     * @return $this
     */
    public function setStatusDataEntry(?StatusDataEntry $statusDataEntry): self
    {
        $this->statusDataEntry = $statusDataEntry;

        return $this;
    }
}
