<gh_stars>0
from sys import argv as arguments
from operator import itemgetter


class ArgumentHandler:
    def __init__(self, args: list):
        assert len(args) == 2, "There must be 2 arguments rather than {}: One for input filename, the other for output filename.".format(len(args))
        self.argument_list = args

    def get_input_filename(self) -> str:
        return self.argument_list[0]

    def get_output_filename(self) -> str:
        return self.argument_list[1]


class FileHandler:
    def __init__(self, input_filename: str, output_filename: str):
        self.input_filename = input_filename
        self.output_filename = output_filename

    def write_output(self, content: str):
        with open(self.output_filename, "w", encoding="utf-8") as output_file:
            output_file.write(content)
            print("Successfully wrote output to {}.".format(self.output_filename))

    def read_input(self):
        with open(self.input_filename, "r", encoding="utf-8") as input_file:
            return input_file.read()


class InputParser:
    def __init__(self, raw_content: str):
        self.__raw_content = raw_content

    @property
    def message_list(self):
        lines = self.__raw_content.split("\n")
        message_list = []
        for line_index in range(len(lines)):
            line = lines[line_index]
            message_proper = [element.strip() for element in line.split("\t")]
            assert len(message_proper) == 3, "Input file is corrupt: There aren\'t enough tab characters at line {}.".format(line_index + 1)
            message_list.append(message_proper)
        return message_list


class Sorter:
    def __init__(self, message_list: list):
        self.__message_list = message_list

    @property
    def message_list(self):
        message_list = []
        for message in self.__message_list:
            if len(message) == 3:
                assert message[0].isdigit() and message[1].isdigit(), "Message IDs and package IDs must be integers: \"{}\"".format(" ".join(message))
                message_list.append([int(message[0]), int(message[1]), message[2]])
        return message_list

    @property
    def message_list_sorted(self):
        return sorted(self.message_list, key=itemgetter(0, 1))


class Printer:
    def __init__(self, message_list_sorted: list, file_handler: FileHandler):
        self.message_list = message_list_sorted
        self.file_handler = file_handler

    def print(self):
        # largest_message_id = 0
        # largest_package_id = 0
        # for message in self.message_list:
        #     if int(message[0]) > largest_message_id:
        #         largest_message_id = int(message[0])
        #     if int(message[1]) > largest_package_id:
        #         largest_package_id = int(message[1])

        # padding_message_id = len(str(largest_message_id)) + 1
        # padding_package_id = len(str(largest_package_id)) + 1

        message_counter = 1
        string = "Message {}\n".format(message_counter)
        for message_index in range(len(self.message_list)):
            message = self.message_list[message_index]

            if message_index >= 1 and message[0] != self.message_list[message_index - 1][0]:
                message_counter += 1
                string += "Message {}\n".format(message_counter)

            string += str(message[0]) + "\t"  # .ljust(padding_message_id)
            string += str(message[1]) + "\t"  # .ljust(padding_package_id)
            string += message[2]
            string += "\n"

        self.file_handler.write_output(string)

    @staticmethod
    def print_both(content, output_filename: str) -> None:
        output_file = open(output_filename, "w")
        print(str(content))
        print(str(content), file=output_file)
        output_file.close()


def main() -> None:
    try:
        arg_handler = ArgumentHandler(arguments[1:])
        file_handler = FileHandler(arg_handler.get_input_filename(), arg_handler.get_output_filename())
        input_parser = InputParser(file_handler.read_input())
        sorter = Sorter(input_parser.message_list)
        printer = Printer(sorter.message_list_sorted, file_handler)
        printer.print()
    except AssertionError as ae:
        message = "[ERROR] " + str(ae)
        if len(arguments) == 3:
            Printer.print_both(message, arguments[2])
        else:
            print(message)
    except FileNotFoundError as fnf:
        Printer.print_both("[ERROR] {}: {}".format(fnf.strerror, fnf.filename), arguments[2])


main()