<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Schema;

use Doctrine\DBAL\Schema\Exception\InvalidPrimaryKeyConstraintDefinition;
use Doctrine\DBAL\Schema\Name\UnqualifiedName;

use function count;

/** @implements OptionallyNamedObject<UnqualifiedName> */
final readonly class PrimaryKeyConstraint implements OptionallyNamedObject
{
    /**
     * @internal Use {@link PrimaryKeyConstraint::editor()} to instantiate an editor and
     *           {@link PrimaryKeyConstraintEditor::create()} to create a primary key constraint.
     *
     * @param ?UnqualifiedName                $name        Name of the primary key constraint. If omitted in the schema
     *                                                     defined by the application, it is considered that the name is
     *                                                     not essential and may be generated by the underlying database
     *                                                     platform.
     * @param non-empty-list<UnqualifiedName> $columnNames
     */
    public function __construct(
        private ?UnqualifiedName $name,
        private array $columnNames,
        private bool $isClustered,
    ) {
        if (count($this->columnNames) < 1) {
            throw InvalidPrimaryKeyConstraintDefinition::columnNamesNotSet();
        }
    }

    public function getObjectName(): ?UnqualifiedName
    {
        return $this->name;
    }

    /**
     * Returns the names of the columns.
     *
     * @return non-empty-list<UnqualifiedName>
     */
    public function getColumnNames(): array
    {
        return $this->columnNames;
    }

    /**
     * Returns whether the primary key constraint is clustered.
     */
    public function isClustered(): bool
    {
        return $this->isClustered;
    }

    /**
     * Instantiates a new primary key constraint editor.
     */
    public static function editor(): PrimaryKeyConstraintEditor
    {
        return new PrimaryKeyConstraintEditor();
    }

    /**
     * Instantiates a new foreign key constraint editor and initializes it with the constraint's properties.
     */
    public function edit(): PrimaryKeyConstraintEditor
    {
        return self::editor()
            ->setName($this->name)
            ->setColumnNames(...$this->columnNames)
            ->setIsClustered($this->isClustered);
    }
}
