# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Logic to read the set of users and groups installed on a system."""

from __future__ import print_function

import collections
import os

from chromite.lib import cros_logging as logging
from chromite.lib import locking
from chromite.lib import osutils


# These fields must be in the order expected in /etc/passwd entries.
User = collections.namedtuple(
    'User', ('user', 'password', 'uid', 'gid', 'gecos', 'home', 'shell'))

# These fields must be in the order expected in /etc/group entries.
Group = collections.namedtuple(
    'Group', ('group', 'password', 'gid', 'users'))


def UserToEntry(user):
  """Returns the database file entry corresponding to |user|."""
  return ':'.join([user.user, user.password, str(user.uid), str(user.gid),
                   user.gecos, user.home, user.shell])


def GroupToEntry(group):
  """Returns the database file entry corresponding to |group|."""
  return ':'.join([group.group, group.password,
                   str(group.gid), ','.join(group.users)])


class UserDB(object):
  """An object that understands the users and groups installed on a system."""

  # Number of times to attempt to acquire the write lock on a database.
  # The max wait time for the lock is the nth triangular number of seconds.
  # So in this case, T(24) * 1 second = 300 seconds.
  _DB_LOCK_RETRIES = 24

  def __init__(self, sysroot):
    self._sysroot = sysroot
    self._user_cache = None
    self._group_cache = None

  @property
  def _user_db_file(self):
    """Returns path to user database (aka /etc/passwd in the sysroot)."""
    return os.path.join(self._sysroot, 'etc', 'passwd')

  @property
  def _group_db_file(self):
    """Returns path to group database (aka /etc/group in the sysroot)."""
    return os.path.join(self._sysroot, 'etc', 'group')

  @property
  def _users(self):
    """Returns a list of User tuples."""
    if self._user_cache is not None:
      return self._user_cache

    self._user_cache = {}
    passwd_contents = osutils.ReadFile(self._user_db_file)

    for line in passwd_contents.splitlines():
      pieces = line.split(':')
      if len(pieces) != 7:
        logging.warning('Ignored invalid line in users file: "%s"', line)
        continue

      user, password, uid, gid, gecos, home, shell = pieces

      try:
        uid_as_int = int(uid)
        gid_as_int = int(gid)
      except ValueError:
        logging.warning('Ignored invalid uid (%s) or gid (%s).', uid, gid)
        continue

      if user in self._user_cache:
        logging.warning('Ignored duplicate user definition for "%s".', user)
        continue

      self._user_cache[user] = User(user=user, password=password,
                                    uid=uid_as_int, gid=gid_as_int,
                                    gecos=gecos, home=home, shell=shell)
    return self._user_cache

  @property
  def _groups(self):
    """Returns a list of Group tuples."""
    if self._group_cache is not None:
      return self._group_cache

    self._group_cache = {}
    group_contents = osutils.ReadFile(self._group_db_file)

    for line in group_contents.splitlines():
      pieces = line.split(':')
      if len(pieces) != 4:
        logging.warning('Ignored invalid line in group file: "%s"', line)
        continue

      group, password, gid, users = pieces

      try:
        gid_as_int = int(gid)
      except ValueError:
        logging.warning('Ignored invalid or gid (%s).', gid)
        continue

      if group in self._group_cache:
        logging.warning('Ignored duplicate group definition for "%s".',
                        group)
        continue

      users = users.split(',')

      self._group_cache[group] = Group(group=group, password=password,
                                       gid=gid_as_int, users=users)
    return self._group_cache

  def GetUserEntry(self, username, skip_lock=False):
    """Returns a user's database entry.

    Args:
      username: name of user to get the entry for.
      skip_lock: True iff we should skip getting a lock before reading the
        database.

    Returns:
      database entry as a string.
    """
    if skip_lock:
      return UserToEntry(self._users[username])

    # Clear the user cache to force ourselves to reparse while holding a lock.
    self._user_cache = None

    with locking.PortableLinkLock(
        self._user_db_file + '.lock', max_retry=self._DB_LOCK_RETRIES):
      return UserToEntry(self._users[username])

  def GetGroupEntry(self, groupname, skip_lock=False):
    """Returns a group's database entry.

    Args:
      groupname: name of group to get the entry for.
      skip_lock: True iff we should skip getting a lock before reading the
        database.

    Returns:
      database entry as a string.
    """
    if skip_lock:
      return GroupToEntry(self._groups[groupname])

    # Clear the group cache to force ourselves to reparse while holding a lock.
    self._group_cache = None

    with locking.PortableLinkLock(
        self._group_db_file + '.lock', max_retry=self._DB_LOCK_RETRIES):
      return GroupToEntry(self._groups[groupname])

  def UserExists(self, username):
    """Returns True iff a user called |username| exists in the database.

    Args:
      username: name of a user (e.g. 'root')

    Returns:
      True iff the given |username| has an entry in /etc/passwd.
    """
    return username in self._users

  def GroupExists(self, groupname):
    """Returns True iff a group called |groupname| exists in the database.

    Args:
      groupname: name of a group (e.g. 'root')

    Returns:
      True iff the given |groupname| has an entry in /etc/group.
    """
    return groupname in self._groups

  def ResolveUsername(self, username):
    """Resolves a username to a uid.

    Args:
      username: name of a user (e.g. 'root')

    Returns:
      The uid of the given username.  Raises ValueError on failure.
    """
    user = self._users.get(username)
    if user:
      return user.uid

    raise ValueError('Could not resolve unknown user "%s" to uid.' % username)

  def ResolveGroupname(self, groupname):
    """Resolves a groupname to a gid.

    Args:
      groupname: name of a group (e.g. 'wheel')

    Returns:
      The gid of the given groupname.  Raises ValueError on failure.
    """
    group = self._groups.get(groupname)
    if group:
      return group.gid

    raise ValueError('Could not resolve unknown group "%s" to gid.' % groupname)

  def AddUser(self, user):
    """Atomically add a user to the database.

    If a user named |user.user| already exists, this method will simply return.

    Args:
      user: user_db.User object to add to database.
    """
    # Try to avoid grabbing the lock in the common case that a user already
    # exists.
    if self.UserExists(user.user):
      logging.info('Not installing user "%s" because it already existed.',
                   user.user)
      return

    # Clear the user cache to force ourselves to reparse.
    self._user_cache = None

    with locking.PortableLinkLock(self._user_db_file + '.lock',
                                  max_retry=self._DB_LOCK_RETRIES):
      # Check that |user| exists under the lock in case we're racing to create
      # this user.
      if self.UserExists(user.user):
        logging.info('Not installing user "%s" because it already existed.',
                     user.user)
        return

      self._users[user.user] = user
      new_users = sorted(self._users.itervalues(), key=lambda u: u.uid)
      contents = '\n'.join([UserToEntry(u) for u in new_users])
      osutils.WriteFile(self._user_db_file, contents, atomic=True, sudo=True)
      print('Added user "%s" to %s:' % (user.user, self._user_db_file))
      print(' - password entry: %s' % user.password)
      print(' - id: %d' % user.uid)
      print(' - group id: %d' % user.gid)
      print(' - gecos: %s' % user.gecos)
      print(' - home: %s' % user.home)
      print(' - shell: %s' % user.shell)

  def AddGroup(self, group):
    """Atomically add a group to the database.

    If a group named |group.group| already exists, this method will simply
    return.

    Args:
      group: user_db.Group object to add to database.
    """
    # Try to avoid grabbing the lock in the common case that a group already
    # exists.
    if self.GroupExists(group.group):
      logging.info('Not installing group "%s" because it already existed.',
                   group.group)
      return

    # Clear the group cache to force ourselves to reparse.
    self._group_cache = None

    with locking.PortableLinkLock(self._group_db_file + '.lock',
                                  max_retry=self._DB_LOCK_RETRIES):
      # Check that |group| exists under the lock in case we're racing to create
      # this group.
      if self.GroupExists(group.group):
        logging.info('Not installing group "%s" because it already existed.',
                     group.group)
        return

      self._groups[group.group] = group
      new_groups = sorted(self._groups.itervalues(), key=lambda g: g.gid)
      contents = '\n'.join([GroupToEntry(g) for g in new_groups])
      osutils.WriteFile(self._group_db_file, contents, atomic=True, sudo=True)
      print('Added group "%s" to %s:' % (group.group, self._group_db_file))
      print(' - group id: %d' % group.gid)
      print(' - password entry: %s' % group.password)
      print(' - user list: %s' % ','.join(group.users))
