
from __future__ import absolute_import
from __future__ import division

import os
import collections

from contextlib import contextmanager


def monotonic_time():
    return os.times()[4]


class Clock(object):

    def __init__(self):
        self._timers = collections.OrderedDict()

    def start(self, name):
        if name in self._timers:
            raise RuntimeError("Timer %r already started" % name)
        self._timers[name] = (monotonic_time(), None)

    def stop(self, name):
        if name not in self._timers:
            raise RuntimeError("Timer %r was not started" % name)
        started, stopped = self._timers[name]
        if stopped is not None:
            raise RuntimeError("Timer %r already stopped" % name)
        self._timers[name] = (started, monotonic_time())

    @contextmanager
    def run(self, name):
        self.start(name)
        try:
            yield
        finally:
            self.stop(name)

    def __repr__(self):
        now = monotonic_time()
        timers = []
        for name, (started, stopped) in self._timers.items():
            if stopped:
                timers.append("%s=%.2f" % (name, stopped - started))
            else:
                timers.append("%s=%.2f*" % (name, now - started))
        return "<Clock(%s)>" % ", ".join(timers)
