#!/usr/bin/env python3
import sys
import curses
from operator import itemgetter
import time

# Number of top items to be displayed
N = 10


def gen_output(item_dict, N=10):
    """
    Generate a formatted output string for the top N items in item_dict.
    
    :param item_dict: A dictionary containing items and their counts
    :param N: The number of top items to be displayed
    :return: A generator yielding formatted strings for each of the top N items
    """
    top_items = dict(sorted(item_dict.items(), key=itemgetter(1), reverse=True)[:N])
    count_length = len(str(max(top_items.values())))

    for i, key in enumerate(top_items):
        yield i, f'{i + 1:3} : [{top_items[key]:{count_length}}] {key}'


def main(screen):
    """
    Main function to read input lines, maintain a count of each unique line, and
    periodically display the top N lines with the highest counts using curses.
    
    :param screen: A curses window object
    """
    if not sys.stdin.isatty():  # Check if the input comes from a pipe
        # Initialize an empty dictionary to store unique input lines and their counts
        toplist = {}

        # Set the next screen update time
        t_update = time.time() + 1

        for line in sys.stdin:
            line = line.strip()

            # Increment the count for each unique input line
            if line in toplist:
                toplist[line] += 1
            else:
                toplist[line] = 1

            # Periodically update the screen with the top N lines
            if time.time() > t_update:
                for idx, line in gen_output(toplist):
                    screen.addstr(idx, 0, line)
                screen.refresh()
                t_update = time.time() + 1

        # Clean up the curses environment and print the final top N lines
        curses.endwin()
        for idx, line in gen_output(toplist):
            print(line)
    else:
        print("Usage: cat input_file.txt | ./top_lines.py")
        print("Or: ./top_lines.py < input_file.txt")

# Initialize the curses library, run the main function, and restore the terminal state
curses.wrapper(main)
