from nengo._vendor import portalocker
from nengo.exceptions import TimeoutError


class FileLock:
    """Lock access to a file (for multithreading)."""

    def __init__(self, filename, timeout=10.0, poll=0.1):
        self.filename = filename
        self.timeout = timeout
        self.poll = poll
        self._lock = portalocker.Lock(
            self.filename, timeout=timeout, check_interval=poll, fail_when_locked=True
        )
        self._acquired = False

    def acquire(self):
        try:
            self._lock.acquire()
            self._acquired = True
        except (portalocker.AlreadyLocked, portalocker.LockException) as e:
            raise TimeoutError(f"Could not acquire lock '{self.filename}'.") from e

    def release(self):
        self._lock.release()
        self._acquired = False

    @property
    def acquired(self):
        return self._acquired

    def __enter__(self):
        self.acquire()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.release()

    def __del__(self):
        self.release()
