<?php

/*
 * This file is part of the API Platform project.
 *
 * (c) Kévin Dunglas <dunglas@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace ApiPlatform\Metadata\GraphQl;

use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Operation as AbstractOperation;
use ApiPlatform\Metadata\Parameters;
use ApiPlatform\State\OptionsInterface;

class Operation extends AbstractOperation
{
    /**
     * @param Link[]|null $links
     * @param array{
     *     class?: string|null,
     *     name?: string,
     * }|string|false|null $input {@see https://api-platform.com/docs/core/dto/#specifying-an-input-or-an-output-data-representation}
     * @param array{
     *     class?: string|null,
     *     name?: string,
     * }|string|false|null $output {@see https://api-platform.com/docs/core/dto/#specifying-an-input-or-an-output-data-representation}
     * @param string|array|bool|null $mercure   {@see https://api-platform.com/docs/core/mercure}
     * @param string|bool|null       $messenger {@see https://api-platform.com/docs/core/messenger/#dispatching-a-resource-through-the-message-bus}
     * @param string|callable|null   $provider  {@see https://api-platform.com/docs/core/state-providers/#state-providers}
     * @param string|callable|null   $processor {@see https://api-platform.com/docs/core/state-processors/#state-processors}
     */
    public function __construct(
        protected ?string $resolver = null,
        protected ?array $args = null,
        protected ?array $extraArgs = null,
        protected ?array $links = null,
        protected ?bool $validateAfterResolver = null,
        protected ?string $securityAfterResolver = null,
        protected ?string $securityMessageAfterResolver = null,

        ?string $shortName = null,
        ?string $class = null,
        ?bool $paginationEnabled = null,
        ?string $paginationType = null,
        ?int $paginationItemsPerPage = null,
        ?int $paginationMaximumItemsPerPage = null,
        ?bool $paginationPartial = null,
        ?bool $paginationClientEnabled = null,
        ?bool $paginationClientItemsPerPage = null,
        ?bool $paginationClientPartial = null,
        ?bool $paginationFetchJoinCollection = null,
        ?bool $paginationUseOutputWalkers = null,
        ?array $order = null,
        ?string $description = null,
        ?array $normalizationContext = null,
        ?array $denormalizationContext = null,
        ?bool $collectDenormalizationErrors = null,
        string|\Stringable|null $security = null,
        ?string $securityMessage = null,
        string|\Stringable|null $securityPostDenormalize = null,
        ?string $securityPostDenormalizeMessage = null,
        string|\Stringable|null $securityPostValidation = null,
        ?string $securityPostValidationMessage = null,
        ?string $deprecationReason = null,
        ?array $filters = null,
        ?array $validationContext = null,
        $input = null,
        $output = null,
        $mercure = null,
        $messenger = null,
        ?bool $elasticsearch = null,
        ?int $urlGenerationStrategy = null,
        ?bool $read = null,
        ?bool $deserialize = null,
        ?bool $validate = null,
        ?bool $write = null,
        ?bool $serialize = null,
        ?bool $fetchPartial = null,
        ?bool $forceEager = null,
        ?int $priority = null,
        ?string $name = null,
        $provider = null,
        $processor = null,
        ?OptionsInterface $stateOptions = null,
        array|Parameters|null $parameters = null,
        ?bool $queryParameterValidationEnabled = null,
        array $extraProperties = [],
    ) {
        parent::__construct(
            shortName: $shortName,
            class: $class,
            paginationEnabled: $paginationEnabled,
            paginationType: $paginationType,
            paginationItemsPerPage: $paginationItemsPerPage,
            paginationMaximumItemsPerPage: $paginationMaximumItemsPerPage,
            paginationPartial: $paginationPartial,
            paginationClientEnabled: $paginationClientEnabled,
            paginationClientItemsPerPage: $paginationClientItemsPerPage,
            paginationClientPartial: $paginationClientPartial,
            paginationFetchJoinCollection: $paginationFetchJoinCollection,
            paginationUseOutputWalkers: $paginationUseOutputWalkers,
            order: $order,
            description: $description,
            normalizationContext: $normalizationContext,
            denormalizationContext: $denormalizationContext,
            collectDenormalizationErrors: $collectDenormalizationErrors,
            security: $security,
            securityMessage: $securityMessage,
            securityPostDenormalize: $securityPostDenormalize,
            securityPostDenormalizeMessage: $securityPostDenormalizeMessage,
            securityPostValidation: $securityPostValidation,
            securityPostValidationMessage: $securityPostValidationMessage,
            deprecationReason: $deprecationReason,
            filters: $filters,
            validationContext: $validationContext,
            input: $input,
            output: $output,
            mercure: $mercure,
            messenger: $messenger,
            elasticsearch: $elasticsearch,
            urlGenerationStrategy: $urlGenerationStrategy,
            read: $read,
            deserialize: $deserialize,
            validate: $validate,
            write: $write,
            serialize: $serialize,
            fetchPartial: $fetchPartial,
            forceEager: $forceEager,
            priority: $priority,
            name: $name,
            provider: $provider,
            processor: $processor,
            stateOptions: $stateOptions,
            parameters: $parameters,
            queryParameterValidationEnabled: $queryParameterValidationEnabled,
            extraProperties: $extraProperties
        );
    }

    public function getResolver(): ?string
    {
        return $this->resolver;
    }

    public function withResolver(?string $resolver = null): self
    {
        $self = clone $this;
        $self->resolver = $resolver;

        return $self;
    }

    public function getArgs(): ?array
    {
        return $this->args;
    }

    public function withArgs(?array $args = null): self
    {
        $self = clone $this;
        $self->args = $args;

        return $self;
    }

    public function getExtraArgs(): ?array
    {
        return $this->extraArgs;
    }

    public function withExtraArgs(?array $extraArgs = null): self
    {
        $self = clone $this;
        $self->extraArgs = $extraArgs;

        return $self;
    }

    /**
     * @return Link[]|null
     */
    public function getLinks(): ?array
    {
        return $this->links;
    }

    /**
     * @param Link[] $links
     */
    public function withLinks(array $links): self
    {
        $self = clone $this;
        $self->links = $links;

        return $self;
    }

    public function canValidateAfterResolver(): ?bool
    {
        return $this->validateAfterResolver;
    }

    public function withValidateAfterResolver(bool $validateAfterResolver = true): self
    {
        $self = clone $this;
        $self->validateAfterResolver = $validateAfterResolver;

        return $self;
    }

    public function getSecurityAfterResolver(): ?string
    {
        return $this->securityAfterResolver;
    }

    public function withSecurityAfterResolver(string $securityAfterResolver): self
    {
        $self = clone $this;
        $self->securityAfterResolver = $securityAfterResolver;

        return $self;
    }

    public function getSecurityMessageAfterResolver(): ?string
    {
        return $this->securityMessageAfterResolver;
    }

    public function withSecurityMessageAfterResolver(string $securityMessageAfterResolver): self
    {
        $self = clone $this;
        $self->securityMessageAfterResolver = $securityMessageAfterResolver;

        return $self;
    }
}
