protected function encodeGroupProtocol(array $values): string
    {
        if (! isset($values['protocol_name'])) {
            throw new ProtocolException('given join group data invalid. `protocol_name` is undefined.');
        }

        $protocolName = self::encodeString($values['protocol_name'], self::PACK_INT16);

        if (! isset($values['version'])) {
            throw new ProtocolException('given data invalid. `version` is undefined.');
        }

        if (! isset($values['subscription']) || empty($values['subscription'])) {
            throw new ProtocolException('given data invalid. `subscription` is undefined.');
        }
        if (! isset($values['user_data'])) {
            $values['user_data'] = '';
        }

        $data  = self::pack(self::BIT_B16, '0');
        $data .= self::encodeArray($values['subscription'], [$this, 'encodeGroupProtocolMetaTopic']);
        $data .= self::encodeString($values['user_data'], self::PACK_INT32);

        return $protocolName . self::encodeString($data, self::PACK_INT32);
    }