# -*- coding: utf-8 -*-
# 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.values(), 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.values(), 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))
