from ircplom.events import (AffectiveEvent, ExceptionEvent, Logger,
                             PayloadMixin, QueueMixin)
 from ircplom.irc_conn import (BaseIrcConnection, IrcConnAbortException,
-                              IrcMessage)
+                              IrcMessage, PORT_SSL)
 
 ClientsDb = dict[UUID, 'Client']
 CHAT_GLOB = '*'
 class IrcConnSetup:
     'All we need to know to set up a new Client connection.'
     hostname: str
+    port: int
     nickname: str
     realname: str
     password: str
         super().__init__(**kwargs)
         self._caps = _CapsManager(self.send)
         self.conn_setup = conn_setup
+        if self.conn_setup.port <= 0:
+            self.conn_setup.port = PORT_SSL
         self.id_ = uuid4()
         self.log = Logger(self._log)
         self.update_login(nick_confirmed=False,
                           nickname=self.conn_setup.nickname)
+        self.log.add(f'connecting {self.conn_setup}')
         self.start_connecting()
 
     def start_connecting(self) -> None:
         def connect(self) -> None:
             try:
                 self.conn = _IrcConnection(hostname=self.conn_setup.hostname,
+                                           port=self.conn_setup.port,
                                            q_out=self.q_out,
                                            client_id=self.id_)
                 self._cput(ClientEvent.make_subtype('on_connect'))
 
     def on_connect(self) -> None:
         'Steps to perform right after connection.'
-        self.log.add(msg='connected to server', chat=CHAT_GLOB)
+        assert self.conn is not None
+        self.log.add('connected to server (SSL: '
+                     f'{"yes" if self.conn.ssl else "no"})', chat=CHAT_GLOB)
         self._caps.challenge('LS', '302')
         self.send(IrcMessage(verb='USER',
                              params=(getuser(), '0', '*',
 
             client_wins[0].prompt.prefix_copy_to(win.prompt)
         return win
 
-    def cmd__connect(self, hostname: str, nickname_and_pw: str, realname: str
+    def cmd__connect(self, host_port: str, nickname_pw: str, realname: str
                      ) -> None:
         'Create Client and pass it via NewClientEvent.'
-        split = nickname_and_pw.split(':', maxsplit=1)
+        split = host_port.split(':', maxsplit=1)
+        hostname = split[0]
+        port = -1
+        if len(split) > 1:
+            to_int = split[1]
+            if to_int.isdigit():
+                port = int(split[1])
+            else:
+                self.log.alert(f'invalid port number: {to_int}')
+                return
+        split = nickname_pw.split(':', maxsplit=1)
         nickname = split[0]
-        pw = split[1] if len(split) > 1 else ''
+        password = split[1] if len(split) > 1 else ''
         self._put(NewClientEvent(
             _ClientKnowingTui(
                 q_out=self.q_out,
-                conn_setup=IrcConnSetup(hostname, nickname, realname, pw))))
+                conn_setup=IrcConnSetup(
+                    hostname, port, nickname, realname, password))))
 
 
 @dataclass
 
 # built-ins
 from abc import ABC, abstractmethod
 from socket import socket, gaierror as socket_gaierror
+from ssl import create_default_context as create_ssl_context
 from typing import Callable, Iterator, NamedTuple, Optional, Self
 # ourselves
 from ircplom.events import Event, Loop, QueueMixin
 
 
+PORT_SSL = 6697
 _TIMEOUT_RECV_LOOP = 0.1
 _TIMEOUT_CONNECT = 5
 _CONN_RECV_BUFSIZE = 1024
-_PORT = 6667
 
 _IRCSPEC_LINE_SEPARATOR = b'\r\n'
 _IRCSPEC_TAG_ESCAPES = ((r'\:', ';'),
 class BaseIrcConnection(QueueMixin, ABC):
     'Collects low-level server-client connection management.'
 
-    def __init__(self, hostname: str, **kwargs) -> None:
+    def __init__(self, hostname: str, port: int, **kwargs) -> None:
         super().__init__(**kwargs)
         self._socket = socket()
+        self.ssl = port == PORT_SSL
+        if self.ssl:
+            self._socket = create_ssl_context().wrap_socket(
+                self._socket, server_hostname=hostname)
         self._socket.settimeout(_TIMEOUT_CONNECT)
         try:
-            self._socket.connect((hostname, _PORT))
+            self._socket.connect((hostname, port))
         except (TimeoutError, socket_gaierror) as e:
             raise IrcConnAbortException(e) from e
         self._socket.settimeout(_TIMEOUT_RECV_LOOP)