# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Exclusive filelocking for all supported platforms."""

from __future__ import print_function

import contextlib
import logging
import os
import sys
import time


class LockError(Exception):
  pass


if sys.platform.startswith('win'):
  # Windows implementation
  import win32imports

  BYTES_TO_LOCK = 1

  def _open_file(lockfile):
    return win32imports.Handle(
        win32imports.CreateFileW(
            lockfile,  # lpFileName
            win32imports.GENERIC_WRITE,  # dwDesiredAccess
            0,  # dwShareMode=prevent others from opening file
            None,  # lpSecurityAttributes
            win32imports.CREATE_ALWAYS,  # dwCreationDisposition
            win32imports.FILE_ATTRIBUTE_NORMAL,  # dwFlagsAndAttributes
            None  # hTemplateFile
        ))

  def _close_file(handle):
    # CloseHandle releases lock too.
    win32imports.CloseHandle(handle)

  def _lock_file(handle):
    ret = win32imports.LockFileEx(
        handle,  # hFile
        win32imports.LOCKFILE_FAIL_IMMEDIATELY
        | win32imports.LOCKFILE_EXCLUSIVE_LOCK,  # dwFlags
        0,  #dwReserved
        BYTES_TO_LOCK,  # nNumberOfBytesToLockLow
        0,  # nNumberOfBytesToLockHigh
        win32imports.Overlapped()  # lpOverlapped
    )
    # LockFileEx returns result as bool, which is converted into an integer
    # (1 == successful; 0 == not successful)
    if ret == 0:
      error_code = win32imports.GetLastError()
      raise OSError('Failed to lock handle (error code: %d).' % error_code)
else:
  # Unix implementation
  import fcntl

  def _open_file(lockfile):
    open_flags = (os.O_CREAT | os.O_WRONLY)
    return os.open(lockfile, open_flags, 0o644)

  def _close_file(fd):
    os.close(fd)

  def _lock_file(fd):
    fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)


def _try_lock(lockfile):
  f = _open_file(lockfile)
  try:
    _lock_file(f)
  except Exception:
    _close_file(f)
    raise
  return lambda: _close_file(f)


def _lock(path, timeout=0):
  """_lock returns function to release the lock if locking was successful.

  _lock also implements simple retry logic."""
  elapsed = 0
  while True:
    try:
      return _try_lock(path + '.locked')
    except (OSError, IOError) as e:
      if elapsed < timeout:
        sleep_time = min(10, timeout - elapsed)
        logging.info(
            'Could not create git cache lockfile; '
            'will retry after sleep(%d).', sleep_time)
        elapsed += sleep_time
        time.sleep(sleep_time)
        continue
      raise LockError("Error locking %s (err: %s)" % (path, str(e)))


@contextlib.contextmanager
def lock(path, timeout=0):
  """Get exclusive lock to path.

  Usage:
    import lockfile
    with lockfile.lock(path, timeout):
      # Do something
      pass

   """
  release_fn = _lock(path, timeout)
  try:
    yield
  finally:
    release_fn()
