public function encode(Message $message, int $options = 0): string
    {
        $ctx = new Context($options);
        $qdCount = $anCount = $nsCount = $arCount = 0;

        foreach ($message->getQuestionRecords() as $record) {
            if (!$this->encodeQuestionRecord($ctx, $record)) {
                goto done;
            }

            $qdCount++;
        }

        foreach ($message->getAnswerRecords() as $record) {
            if (!$this->encodeResourceRecord($ctx, $record)) {
                goto done;
            }

            $anCount++;
        }

        foreach ($message->getAuthorityRecords() as $record) {
            if (!$this->encodeResourceRecord($ctx, $record)) {
                goto done;
            }

            $nsCount++;
        }

        foreach ($message->getAdditionalRecords() as $record) {
            if (!$this->encodeResourceRecord($ctx, $record)) {
                goto done;
            }

            $arCount++;
        }

        done:
        $packet = $this->encodeHeader($ctx, $message, $qdCount, $anCount, $nsCount, $arCount) . $ctx->data;

        if (!($options & EncodingOptions::FORMAT_TCP)) {
            \assert(
                \strlen($packet) <= 512,
                new \Error('UDP packet exceeds 512 byte limit: got ' . \strlen($packet) . ' bytes')
            );

            return $packet;
        }

        \assert(
            \strlen($packet) <= 65535,
            new \Error('TCP packet exceeds 65535 byte limit: got ' . \strlen($packet) . ' bytes')
        );

        return \pack('n', \strlen($packet)) . $packet;
    }