import socket
import threading
import re
import os
import sys

# Ochistka konsoli
os.system('cls' if os.name == 'nt' else 'clear')

# Konstanty
HOST = "147.185.221.19"
PORT = 42439
SEPARATOR = "-" * 50  # Razdelitel'naya liniya

# Global'nye peremennye
stop_event = threading.Event()
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
last_sent_message = None
chat_history = []  # Hranenie istorii soobshchenij


def extract_message_content(full_message):
    """
    Izvlechenie soderzhimogo soobshcheniya (posle ':').
    Esli ':' net, vozvrashchaetsya polnoe soobshchenie.
    """
    match = re.match(r"^.*?:\s*(.*)$", full_message)
    return match.group(1) if match else full_message


def update_console():
    """
    Obnovlenie konsoli dlya otobrazheniya chata i stroki vvoda.
    """
    os.system('cls' if os.name == 'nt' else 'clear')
    print("=" * 50)
    print("      DMconnect Client")
    print("  Copyright (c) 1998 Octavian")
    print("=" * 50)
    print("\nIstoriya soobshchenij:\n")
    for message in chat_history:
        print(message)
    print("\n" + SEPARATOR)
    sys.stdout.write("> ")  # Stroka vvoda
    sys.stdout.flush()


def receive_messages():
    """
    Poluchenie soobshchenij ot servera.
    """
    global last_sent_message
    while not stop_event.isSet():
        try:
            # Poluchenie soobshcheniya
            message = client_socket.recv(1024).strip()
            if not message:
                break

            # Popytka dekodirovaniya
            try:
                message = message.strip()
            except Exception:
                pass

            # Izvlechenie soderzhimogo
            message_content = extract_message_content(message)

            # Dobavlenie v istoriyu soobshchenij
            if message_content != last_sent_message:
                chat_history.append(str(message))
                update_console()
            else:
                last_sent_message = None
        except Exception, e:
            if not stop_event.isSet():
                chat_history.append("[Error]: Unable to receive message - " + str(e))
                update_console()
            break


def start_receiving_thread():
    """
    Zapusk potoka dlya polucheniya soobshchenij s servera.
    """
    receive_thread = threading.Thread(target=receive_messages)
    receive_thread.setDaemon(True)
    receive_thread.start()


def main():
    global last_sent_message

    # Podklyuchenie k serveru
    try:
        client_socket.connect((HOST, PORT))
        start_receiving_thread()
        chat_history.append("[Info]: Connected to the server.")
        update_console()
    except Exception, e:
        print("[Error]: Connection failed - " + str(e))
        return

    # Osnovnoj cikl otpravki soobshchenij
    while True:
        try:
            msg = raw_input().strip()  # Vvod soobshcheniya ot pol'zovatelya
            if msg.lower() == "exit":  # Vyhod iz programmy
                chat_history.append("[Info]: Disconnecting...")
                update_console()
                stop_event.set()
                client_socket.close()
                break

            if msg:  # Otpravka soobshcheniya
                last_sent_message = msg
                client_socket.send(msg)
                chat_history.append("[You]: " + str(msg))
                update_console()
        except KeyboardInterrupt:
            chat_history.append("[Info]: Exiting...")
            update_console()
            stop_event.set()
            client_socket.close()
            break
        except Exception, e:
            chat_history.append("[Error]: An error occurred - " + str(e))
            update_console()


if __name__ == "__main__":
    main()