#!/usr/bin/python
#
# Copyright 2010 Google Inc. All Rights Reserved.

"""Script to lock/unlock machines."""

__author__ = "asharif@google.com (Ahmad Sharif)"

import datetime
import fcntl
import getpass
import glob
import json
import optparse
import os
import socket
import sys
import time

from utils import logger

LOCK_SUFFIX = "_check_lock_liveness"

# The locks file directory REQUIRES that 'group' only has read/write
# privileges and 'world' has no privileges.  So the mask must be
# '0027': 0777 - 0027 = 0750.
LOCK_MASK = 0027

def FileCheckName(name):
  return name + LOCK_SUFFIX


def OpenLiveCheck(file_name):
  with FileCreationMask(LOCK_MASK):
    fd = open(file_name, "a+w")
  try:
    fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
  except IOError:
    raise
  return fd


class FileCreationMask(object):
  def __init__(self, mask):
    self._mask = mask

  def __enter__(self):
    self._old_mask = os.umask(self._mask)

  def __exit__(self, type, value, traceback):
    os.umask(self._old_mask)


class LockDescription(object):
  """The description of the lock."""

  def __init__(self, desc=None):
    try:
      self.owner = desc["owner"]
      self.exclusive = desc["exclusive"]
      self.counter = desc["counter"]
      self.time = desc["time"]
      self.reason = desc["reason"]
      self.auto = desc["auto"]
    except (KeyError, TypeError):
      self.owner = ""
      self.exclusive = False
      self.counter = 0
      self.time = 0
      self.reason = ""
      self.auto = False

  def IsLocked(self):
    return self.counter or self.exclusive

  def __str__(self):
    return " ".join(["Owner: %s" % self.owner,
                     "Exclusive: %s" % self.exclusive,
                     "Counter: %s" % self.counter,
                     "Time: %s" % self.time,
                     "Reason: %s" % self.reason,
                     "Auto: %s" % self.auto])


class FileLock(object):
  """File lock operation class."""
  FILE_OPS = []

  def __init__(self, lock_filename):
    self._filepath = lock_filename
    lock_dir = os.path.dirname(lock_filename)
    assert os.path.isdir(lock_dir), (
        "Locks dir: %s doesn't exist!" % lock_dir)
    self._file = None

  @classmethod
  def AsString(cls, file_locks):
    stringify_fmt = "%-30s %-15s %-4s %-4s %-15s %-40s %-4s"
    header = stringify_fmt % ("machine", "owner", "excl", "ctr",
                              "elapsed", "reason", "auto")
    lock_strings = []
    for file_lock in file_locks:

      elapsed_time = datetime.timedelta(
          seconds=int(time.time() - file_lock._description.time))
      elapsed_time = "%s ago" % elapsed_time
      lock_strings.append(stringify_fmt %
                          (os.path.basename(file_lock._filepath),
                           file_lock._description.owner,
                           file_lock._description.exclusive,
                           file_lock._description.counter,
                           elapsed_time,
                           file_lock._description.reason,
                           file_lock._description.auto))
    table = "\n".join(lock_strings)
    return "\n".join([header, table])

  @classmethod
  def ListLock(cls, pattern, locks_dir):
    if not locks_dir:
      locks_dir = Machine.LOCKS_DIR
    full_pattern = os.path.join(locks_dir, pattern)
    file_locks = []
    for lock_filename in glob.glob(full_pattern):
      if LOCK_SUFFIX in lock_filename:
        continue
      file_lock = FileLock(lock_filename)
      with file_lock as lock:
        if lock.IsLocked():
          file_locks.append(file_lock)
    logger.GetLogger().LogOutput("\n%s" % cls.AsString(file_locks))

  def __enter__(self):
    with FileCreationMask(LOCK_MASK):
      try:
        self._file = open(self._filepath, "a+")
        self._file.seek(0, os.SEEK_SET)

        if fcntl.flock(self._file.fileno(), fcntl.LOCK_EX) == -1:
          raise IOError("flock(%s, LOCK_EX) failed!" % self._filepath)

        try:
          desc = json.load(self._file)
        except (EOFError, ValueError):
          desc = None
        self._description = LockDescription(desc)

        if self._description.exclusive and self._description.auto:
          locked_byself = False
          for fd in self.FILE_OPS:
            if fd.name == FileCheckName(self._filepath):
              locked_byself = True
              break
          if not locked_byself:
            try:
              fp = OpenLiveCheck(FileCheckName(self._filepath))
            except IOError:
              pass
            else:
              self._description = LockDescription()
              fcntl.lockf(fp, fcntl.LOCK_UN)
              fp.close()
        return self._description
      # Check this differently?
      except IOError as ex:
        logger.GetLogger().LogError(ex)
        return None

  def __exit__(self, type, value, traceback):
    self._file.truncate(0)
    self._file.write(json.dumps(self._description.__dict__, skipkeys=True))
    self._file.close()

  def __str__(self):
    return self.AsString([self])


class Lock(object):
  def __init__(self, lock_file, auto=True):
    self._to_lock = os.path.basename(lock_file)
    self._lock_file = lock_file
    self._logger = logger.GetLogger()
    self._auto = auto

  def NonBlockingLock(self, exclusive, reason=""):
    with FileLock(self._lock_file) as lock:
      if lock.exclusive:
        self._logger.LogError(
            "Exclusive lock already acquired by %s. Reason: %s" %
            (lock.owner, lock.reason))
        return False

      if exclusive:
        if lock.counter:
          self._logger.LogError("Shared lock already acquired")
          return False
        lock_file_check = FileCheckName(self._lock_file)
        fd = OpenLiveCheck(lock_file_check)
        FileLock.FILE_OPS.append(fd)

        lock.exclusive = True
        lock.reason = reason
        lock.owner = getpass.getuser()
        lock.time = time.time()
        lock.auto = self._auto
      else:
        lock.counter += 1
    self._logger.LogOutput("Successfully locked: %s" % self._to_lock)
    return True

  def Unlock(self, exclusive, force=False):
    with FileLock(self._lock_file) as lock:
      if not lock.IsLocked():
        self._logger.LogWarning("Can't unlock unlocked machine!")
        return True

      if lock.exclusive != exclusive:
        self._logger.LogError("shared locks must be unlocked with --shared")
        return False

      if lock.exclusive:
        if lock.owner != getpass.getuser() and not force:
          self._logger.LogError("%s can't unlock lock owned by: %s" %
                                (getpass.getuser(), lock.owner))
          return False
        if lock.auto != self._auto:
          self._logger.LogError("Can't unlock lock with different -a"
                                " parameter.")
          return False
        lock.exclusive = False
        lock.reason = ""
        lock.owner = ""

        if self._auto:
          del_list = [i for i in FileLock.FILE_OPS
                      if i.name == FileCheckName(self._lock_file)]
          for i in del_list:
            FileLock.FILE_OPS.remove(i)
          for f in del_list:
            fcntl.lockf(f, fcntl.LOCK_UN)
            f.close()
          del del_list
          os.remove(FileCheckName(self._lock_file))

      else:
        lock.counter -= 1
    return True


class Machine(object):
  LOCKS_DIR = "/google/data/rw/users/mo/mobiletc-prebuild/locks"

  def __init__(self, name, locks_dir=LOCKS_DIR, auto=True):
    self._name = name
    self._auto = auto
    try:
      self._full_name = socket.gethostbyaddr(name)[0]
    except socket.error:
      self._full_name = self._name
    self._full_name = os.path.join(locks_dir, self._full_name)

  def Lock(self, exclusive=False, reason=""):
    lock = Lock(self._full_name, self._auto)
    return lock.NonBlockingLock(exclusive, reason)

  def TryLock(self, timeout=300, exclusive=False, reason=""):
    locked = False
    sleep = timeout / 10
    while True:
      locked = self.Lock(exclusive, reason)
      if locked or not timeout >= 0:
        break
      print "Lock not acquired for {0}, wait {1} seconds ...".format(
          self._name, sleep)
      time.sleep(sleep)
      timeout -= sleep
    return locked

  def Unlock(self, exclusive=False, ignore_ownership=False):
    lock = Lock(self._full_name, self._auto)
    return lock.Unlock(exclusive, ignore_ownership)


def Main(argv):
  """The main function."""
  parser = optparse.OptionParser()
  parser.add_option("-r",
                    "--reason",
                    dest="reason",
                    default="",
                    help="The lock reason.")
  parser.add_option("-u",
                    "--unlock",
                    dest="unlock",
                    action="store_true",
                    default=False,
                    help="Use this to unlock.")
  parser.add_option("-l",
                    "--list_locks",
                    dest="list_locks",
                    action="store_true",
                    default=False,
                    help="Use this to list locks.")
  parser.add_option("-f",
                    "--ignore_ownership",
                    dest="ignore_ownership",
                    action="store_true",
                    default=False,
                    help="Use this to force unlock on a lock you don't own.")
  parser.add_option("-s",
                    "--shared",
                    dest="shared",
                    action="store_true",
                    default=False,
                    help="Use this for a shared (non-exclusive) lock.")
  parser.add_option("-d",
                    "--dir",
                    dest="locks_dir",
                    action="store",
                    default=Machine.LOCKS_DIR,
                    help="Use this to set different locks_dir")

  options, args = parser.parse_args(argv)

  options.locks_dir = os.path.abspath(options.locks_dir)
  exclusive = not options.shared

  if not options.list_locks and len(args) != 2:
    logger.GetLogger().LogError(
        "Either --list_locks or a machine arg is needed.")
    return 1

  if len(args) > 1:
    machine = Machine(args[1], options.locks_dir, auto=False)
  else:
    machine = None

  if options.list_locks:
    FileLock.ListLock("*", options.locks_dir)
    retval = True
  elif options.unlock:
    retval = machine.Unlock(exclusive, options.ignore_ownership)
  else:
    retval = machine.Lock(exclusive, options.reason)

  if retval:
    return 0
  else:
    return 1

if __name__ == "__main__":
  sys.exit(Main(sys.argv))
