from datetime import datetime
from typing import OrderedDict


def pretty_date(time):
    """Transforms a datetime object or a int() Epoch timestamp into a
    pretty string like 'an hour ago', 'Yesterday', '3 months ago',
    'just now', etc

    Based on https://stackoverflow.com/a/1551394/713980
    Adapted by sven1103
    """
    now = datetime.now()
    if isinstance(time, datetime):
        diff = now - time
    else:
        diff = now - datetime.fromtimestamp(time)
    second_diff = diff.seconds
    day_diff = diff.days

    pretty_msg = OrderedDict()
    pretty_msg[0] = [(float('inf'), 1, 'from the future')]
    pretty_msg[1] = [
            (10, 1, "just now"),
            (60, 1, "{sec:.0f} seconds ago"),
            (120, 1, "a minute ago"),
            (3600, 60, "{sec:.0f} minutes ago"),
            (7200, 1, "an hour ago"),
            (86400, 3600, "{sec:.0f} hours ago")
        ]
    pretty_msg[2] = [(float('inf'), 1, 'yesterday')]
    pretty_msg[7] = [(float('inf'), 1, '{days:.0f} day{day_s} ago')]
    pretty_msg[31] = [(float('inf'), 7, '{days:.0f} week{day_s} ago')]
    pretty_msg[365] = [(float('inf'), 30, '{days:.0f} months ago')]
    pretty_msg[float('inf')] = [(float('inf'), 365, '{days:.0f} year{day_s} ago')]

    for days, seconds in pretty_msg.items():
        if day_diff < days:
            for sec in seconds:
                if second_diff < sec[0]:
                    return sec[2].format(
                            days = day_diff/sec[1],
                            sec = second_diff/sec[1],
                            day_s = 's' if day_diff/sec[1] > 1 else ''
                        )
    return '... time is relative anyway'