# Ben Stabley
# GEO242 Midterm
# 2023-05-20


from city import City


def read_cities(filepath: str) -> list[City]:
    """Read and parse Cities from filepath."""
    with open(filepath) as file:
        return [City.parse_line(line) for line in file.readlines()]


def print_cities(cities: list[City]):
    """Print each city."""
    print("\n".join([str(c) for c in cities]))


# satisfies the requirements for "first function" described in the midterm assignment.
def read_and_print_cities(filepath: str) -> list[City]:
    """Read cities from filepath, print each, and return a list of Cities."""
    cities = read_cities(filepath)
    print_cities(cities)
    return cities


# satisfies the requirements for the "second function" described in the midterm assignment.
def print_distances(cities: list[City], print_header: bool = True):
    """
    Print a table of every combination (cartesian product) of city pairs with the
    distance between each pair. Does not print the combination when each city
    in the pair is the same city. The header for the table can be optionally
    hidden.
    """
    name_col_width = 16
    dist_col_width = 6
    # this fmt string is kinda a mess with all the braces
    outfmt = f"{{:{name_col_width}}}{{:{name_col_width}}}{{:{dist_col_width},.2f}}"

    if print_header:
        headerfmt = f"{{:{name_col_width}}}{{:{name_col_width}}}{{:{dist_col_width}}}"
        print(headerfmt.format("From", "To", "Distance"))

    cities.sort(key=lambda c: c.name)  # sort cities in-place by name ascending
    for a in cities:
        for b in cities:
            if a == b:
                continue
            dist = a.dist_to(b)
            print(outfmt.format(a.name, b.name, dist))


# -----------------------------------------------------------------
# Application main code
# -----------------------------------------------------------------
if __name__ == "__main__":
    cities = read_and_print_cities(filepath="cities.txt")
    print()  # print blank line
    print_distances(cities)
