<?php

declare(strict_types=1);

namespace Ddeboer\Imap;

use Ddeboer\Imap\Exception\AuthenticationFailedException;
use Ddeboer\Imap\Exception\ResourceCheckFailureException;

/**
 * An IMAP server.
 */
final class Server implements ServerInterface
{
    private string $hostname;
    private string $port;
    private string $flags;
    /**
     * @var mixed[]
     */
    private array $parameters;
    private int $options;
    private int $retries;

    /**
     * Constructor.
     *
     * @param string  $hostname   Internet domain name or bracketed IP address
     *                            of server
     * @param string  $port       TCP port number
     * @param string  $flags      Optional flags
     * @param mixed[] $parameters Connection parameters
     * @param int     $options    Connection options
     * @param int     $retries    Retries number
     */
    public function __construct(
        string $hostname,
        string $port = '993',
        string $flags = '/imap/ssl/validate-cert',
        array $parameters = [],
        int $options = 0,
        int $retries = 1
    ) {
        if (!\function_exists('imap_open')) {
            throw new \RuntimeException('IMAP extension must be enabled');
        }

        $this->hostname   = $hostname;
        $this->port       = $port;
        $this->flags      = '' !== $flags ? '/' . \ltrim($flags, '/') : '';
        $this->parameters = $parameters;
        $this->options    = $options;
        $this->retries    = $retries;
    }

    /**
     * Authenticate connection.
     *
     * @param string $username Username
     * @param string $password Password
     *
     * @throws AuthenticationFailedException
     */
    public function authenticate(string $username, string $password): ConnectionInterface
    {
        $errorMessage = null;
        $errorNumber  = 0;
        \set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
            $errorMessage = $message;
            $errorNumber = $nr;

            return true;
        });

        $resource = \imap_open(
            $this->getServerString(),
            $username,
            $password,
            $this->options,
            $this->retries,
            $this->parameters
        );

        \restore_error_handler();

        if (false === $resource || null !== $errorMessage) {
            throw new AuthenticationFailedException(\sprintf(
                'Authentication failed for user "%s"%s',
                $username,
                null !== $errorMessage ? ': ' . $errorMessage : ''
            ), $errorNumber);
        }

        $check = \imap_check($resource);

        if (false === $check) {
            throw new ResourceCheckFailureException('Resource check failure');
        }

        $mailbox       = $check->Mailbox;
        $connection    = $mailbox;
        $curlyPosition = \strpos($mailbox, '}');
        if (false !== $curlyPosition) {
            $connection = \substr($mailbox, 0, $curlyPosition + 1);
        }

        // These are necessary to get rid of PHP throwing IMAP errors
        \imap_errors();
        \imap_alerts();

        return new Connection(new ImapResource($resource), $connection);
    }

    /**
     * Glues hostname, port and flags and returns result.
     */
    private function getServerString(): string
    {
        return \sprintf(
            '{%s%s%s}',
            $this->hostname,
            '' !== $this->port ? ':' . $this->port : '',
            $this->flags
        );
    }
}
