private void OnMessageReceivedEventHandler(MessageData messageData)
        {
            Dispatcher.Invoke(() =>
                {
                    _logger.Debug($"Received message: '{messageData.UserInfo.Message}' from '{messageData.UserInfo.Username}'" +
                                  $" Message type: '{messageData.UserInfo.MessageType}'");
                    if (messageData.UserInfo.MessageType == MessageType.Connect ||
                        messageData.UserInfo.MessageType == MessageType.Disconnect)
                    {
                        ChatTextBox.AppendText($"{messageData.UserInfo.Message}{Environment.NewLine}");
                    }

                    else if (messageData.UserInfo.MessageType == MessageType.ParameterE)
                    {
                        encryption.serverE = new BigInteger(messageData.UserInfo.Message,10);
                    }
                    else if (messageData.UserInfo.MessageType == MessageType.ParameterN)
                    {
                        encryption.serverN = new BigInteger(messageData.UserInfo.Message,10);
                    }

                    else if (messageData.UserInfo.MessageType == MessageType.CryptoMessage)
                    {
                        // encrypted symm key, receiver, encrypted message
                        string[] receiverUsernameAndMessage = messageData.UserInfo.Message.Split(new char[] { ',' }, 3);
                        if (_username == receiverUsernameAndMessage[1])
                        {
                            string decryptedSymmKey = encryptionRsa.DecryptSymmetricKey(receiverUsernameAndMessage[0],
                                encryption.D, encryption.N);
                            EncryptionAES aes = new EncryptionAES(decryptedSymmKey);
                            string message = aes.Decrypt(receiverUsernameAndMessage[2]);
                            message.TrimEnd();
                            ChatTextBox.AppendText($"{messageData.UserInfo.Username}: (private) {message} {Environment.NewLine}");
                        }
                        else
                        {
                            ChatTextBox.AppendText($"{messageData.UserInfo.Username}: {receiverUsernameAndMessage[2]}" +
                                                   $"{Environment.NewLine}");
                        }
                    }
                    else
                    {
                        ChatTextBox.AppendText(
                            $"{messageData.UserInfo.Username}: {messageData.UserInfo.Message}{Environment.NewLine}");
                    }
                });
        }
        public void HandleMessage(ConnectionModel connection, MessageData messageData)
        {
            if (connection == null)
                throw new ArgumentNullException(nameof(connection));

            MessageData messageToSend = new MessageData();

            switch(messageData.UserInfo.MessageType)
            {
                case MessageType.Connect:
                    messageToSend.UserInfo.MessageType = MessageType.Connect;
                    messageToSend.UserInfo.Username = messageData.UserInfo.Username;
                    if (connection.ConnectionInformation == null)
                    {
                        connection.ConnectionInformation = new ConnectionInformation(messageToSend.UserInfo.Username,
                            connection.Id);
                        Program.ConnectionManager.UsersList.Add(connection.ConnectionInformation);
                    }
                    else
                    {
                        connection.ConnectionInformation.ChangeUsername(messageData.UserInfo.Username);
                    }
                    messageToSend.UserInfo.Message = ">>> " + messageData.UserInfo.Username + " connected";
                    Program.ConnectionManager.SendAll(messageToSend.ToByte());
                    break;

                case MessageType.Disconnect:
                    messageToSend.UserInfo.MessageType = MessageType.Disconnect;
                    foreach (var connections in Program.ConnectionManager.UsersList)
                    {
                        if (connections.Id == connection.Id)
                        {
                            Program.ConnectionManager.UsersList.Remove(connections);
                            break;
                        }
                    }
                    messageToSend.UserInfo.Message = "<<< " + messageData.UserInfo.Username + " disconnected";
                    Program.ConnectionManager.SendAll(messageToSend.ToByte());
                    break;

                case MessageType.Message:
                    messageToSend.UserInfo.Username = messageData.UserInfo.Username;
                    messageToSend.UserInfo.Message = messageData.UserInfo.Message;
                    Program.ConnectionManager.SendAll(messageToSend.ToByte());
                    break;

                case MessageType.ParameterE:
                    connection.ConnectionInformation.ChangeE(new BigInteger(messageData.UserInfo.Message, 10));
                    messageToSend.UserInfo.Username = "******";
                    messageToSend.UserInfo.MessageType = MessageType.ParameterE;
                    messageToSend.UserInfo.Message = _serverKeys.E.ToString(10);
                    Program.ConnectionManager.SendAll(messageToSend.ToByte());
                    break;

                case MessageType.ParameterN:
                    connection.ConnectionInformation.ChangeN(new BigInteger(messageData.UserInfo.Message, 10));
                    messageToSend.UserInfo.Username = "******";
                    messageToSend.UserInfo.MessageType = MessageType.ParameterN;
                    messageToSend.UserInfo.Message = _serverKeys.N.ToString(10);
                    Program.ConnectionManager.SendAll(messageToSend.ToByte());
                    break;

                case MessageType.SymmetricKey:
                    foreach (var user in Program.ConnectionManager.UsersList)
                    {
                        if (user.Username == messageData.UserInfo.Username)
                        {
                            user.symmKey = messageData.UserInfo.Message; //encrypted
                            break;
                        }
                    }
                    break;

                case MessageType.CryptoMessage:
                    // "name,message"
                    string[] receiverUsernameAndMessage = messageData.UserInfo.Message.Split(new char[] {','}, 2);
                    string encryptedMessage = encryptMessage(receiverUsernameAndMessage[1],
                        receiverUsernameAndMessage[0], messageData.UserInfo.Username);

                    //encrypted symm key, receiver, encrypted message
                    messageToSend.UserInfo.Username = messageData.UserInfo.Username;
                    messageToSend.UserInfo.MessageType = MessageType.CryptoMessage;
                    messageToSend.UserInfo.Message = symmKeyBytes + "," + receiverUsernameAndMessage[0] + "," + encryptedMessage;
                    Program.ConnectionManager.SendAll(messageToSend.ToByte());
                    break;
            }

            _logger.Debug($"Received message from: '{messageData.UserInfo.Username}'. Message: '{messageData.UserInfo.Message}'. Message Type: " +
                          $"{messageData.UserInfo.MessageType}");
            //Program.ConnectionManager.messageQueue.RemoveAt(0);
        }
        private void Window_Loaded(Object sender, RoutedEventArgs e)
        {
            //Catch all exceptions
            Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
            Application.Current.Exit += Current_Exit;

            String serverIp = ConfigurationManager.AppSettings["ServerIp"];
            String serverPort = ConfigurationManager.AppSettings["ServerPort"];

            _logger.Info($"Client will try to connect to {serverIp}:{serverPort}");

            _connector = new ConnectionConnector(new IPEndPoint(IPAddress.Parse(serverIp), UInt16.Parse(serverPort)), _username);
            MessageData messageData = new MessageData
            {
                UserInfo =
                {
                    Username = _username,
                    MessageType = MessageType.Connect
                }
            };
            _connector.Send(messageData.ToByte());

            bool succeeded = false;
            while (succeeded == false)
            {
                try
                {
                    encryptionRsa = new EncryptionRSA(true);
                    encryption = new Encryption(encryptionRsa.D, encryptionRsa.E,encryptionRsa.N);
                    messageData.UserInfo.MessageType = MessageType.ParameterN;
                    messageData.UserInfo.Message = encryption.N.ToString(10);
                    _connector.Send(messageData.ToByte());

                    //kartais N neissiuncia kazkodel
                    messageData.UserInfo.MessageType = MessageType.ParameterE;
                    messageData.UserInfo.Message = encryption.E.ToString(10);
                    _connector.Send(messageData.ToByte());

                    succeeded = true;

                }
                catch (Exception)
                {
                }
            }

            _connector.OnMessageReceived += OnMessageReceivedEventHandler;
        }