<?php

declare(strict_types=1);

namespace Ddeboer\Imap;

use Ddeboer\Imap\Exception\CreateMailboxException;
use Ddeboer\Imap\Exception\DeleteMailboxException;
use Ddeboer\Imap\Exception\ImapGetmailboxesException;
use Ddeboer\Imap\Exception\ImapNumMsgException;
use Ddeboer\Imap\Exception\ImapQuotaException;
use Ddeboer\Imap\Exception\MailboxDoesNotExistException;

/**
 * A connection to an IMAP server that is authenticated for a user.
 */
final class Connection implements ConnectionInterface
{
    private ImapResourceInterface $resource;
    private string $server;
    /**
     * @var null|MailboxInterface[]
     */
    private ?array $mailboxes = null;
    /**
     * @var null|array<int|string, \stdClass>
     */
    private ?array $mailboxNames = null;

    /**
     * Constructor.
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(ImapResourceInterface $resource, string $server)
    {
        $this->resource = $resource;
        $this->server   = $server;
    }

    public function getResource(): ImapResourceInterface
    {
        return $this->resource;
    }

    public function expunge(): bool
    {
        return \imap_expunge($this->resource->getStream());
    }

    public function close(int $flag = 0): bool
    {
        $this->resource->clearLastMailboxUsedCache();

        return \imap_close($this->resource->getStream(), $flag);
    }

    public function getQuota(string $root = 'INBOX'): array
    {
        $errorMessage = null;
        $errorNumber  = 0;
        \set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
            $errorMessage = $message;
            $errorNumber = $nr;

            return true;
        });

        $return = \imap_get_quotaroot($this->resource->getStream(), $root);

        \restore_error_handler();

        if (false === $return || null !== $errorMessage) {
            throw new ImapQuotaException(
                \sprintf(
                    'IMAP Quota request failed for "%s"%s',
                    $root,
                    null !== $errorMessage ? ': ' . $errorMessage : ''
                ),
                $errorNumber
            );
        }

        return $return;
    }

    public function getMailboxes(): array
    {
        $this->initMailboxNames();
        \assert(null !== $this->mailboxNames);

        if (null === $this->mailboxes) {
            $this->mailboxes = [];
            foreach ($this->mailboxNames as $mailboxName => $mailboxInfo) {
                $this->mailboxes[(string) $mailboxName] = $this->getMailbox((string) $mailboxName);
            }
        }

        return $this->mailboxes;
    }

    public function hasMailbox(string $name): bool
    {
        $this->initMailboxNames();
        \assert(null !== $this->mailboxNames);

        return isset($this->mailboxNames[$name]);
    }

    public function getMailbox(string $name): MailboxInterface
    {
        if (false === $this->hasMailbox($name)) {
            throw new MailboxDoesNotExistException(\sprintf('Mailbox name "%s" does not exist', $name));
        }
        \assert(isset($this->mailboxNames[$name]));

        return new Mailbox($this->resource, $name, $this->mailboxNames[$name]);
    }

    #[\ReturnTypeWillChange]
    public function count()
    {
        $return = \imap_num_msg($this->resource->getStream());

        if (false === $return) {
            throw new ImapNumMsgException('imap_num_msg failed');
        }

        return $return;
    }

    public function ping(): bool
    {
        return \imap_ping($this->resource->getStream());
    }

    public function createMailbox(string $name): MailboxInterface
    {
        if (false === \imap_createmailbox($this->resource->getStream(), $this->server . \mb_convert_encoding($name, 'UTF7-IMAP', 'UTF-8'))) {
            throw new CreateMailboxException(\sprintf('Can not create "%s" mailbox at "%s"', $name, $this->server));
        }

        $this->mailboxNames = $this->mailboxes = null;
        $this->resource->clearLastMailboxUsedCache();

        return $this->getMailbox($name);
    }

    public function deleteMailbox(MailboxInterface $mailbox): void
    {
        if (false === \imap_deletemailbox($this->resource->getStream(), $mailbox->getFullEncodedName())) {
            throw new DeleteMailboxException(\sprintf('Mailbox "%s" could not be deleted', $mailbox->getName()));
        }

        $this->mailboxes = $this->mailboxNames = null;
        $this->resource->clearLastMailboxUsedCache();
    }

    private function initMailboxNames(): void
    {
        if (null !== $this->mailboxNames) {
            return;
        }

        $this->mailboxNames = [];
        $mailboxesInfo      = \imap_getmailboxes($this->resource->getStream(), $this->server, '*');
        if (!\is_array($mailboxesInfo)) {
            throw new ImapGetmailboxesException('imap_getmailboxes failed');
        }

        foreach ($mailboxesInfo as $mailboxInfo) {
            $name = \mb_convert_encoding(\str_replace($this->server, '', $mailboxInfo->name), 'UTF-8', 'UTF7-IMAP');
            \assert(\is_string($name));

            $this->mailboxNames[$name] = $mailboxInfo;
        }
    }
}
