"""A helper script to setup and start bots on a host machine.

  This script does following:
    - Parses devicemap.yaml and finds out how many bots are needed for a host.
    - Check if bot directories exist and create bot directories as needed.
    - Create systemd configs and bot startup script.
    - Run systemctl start swarming_bot--<bot number> for any bots not currently
      running

NOTE: This script is being invoked from a puppet manifest and will not have
access to rest of the test code or python virtual environment. So keep in mind
to not use any non standard python libraries.

Example usage:
  python bot_setup.py bot_setup.py \
    --user gtvchrome --group gtvchrome --swarm-bots-home /home/bots_home \
    --gsutil-dir /home/gsutil_home --gsutil-boto /home/.boto \
    --fragglerock-key /home/fragglerock_service_key.json \
    --eurtest-binaries /home/eurtest_binaries --venv /home/bots-home/swarm_env
"""

import argparse
import errno
import grp
import logging
import os
import pwd
import shutil
import socket
import string
import subprocess
import sys
import yaml

# This code runs on catatester host and doesn't have whole code tree, hence
# do relative import.
try:
  from catatester.devicemap import devicemap_lib
except ImportError:
  import devicemap_lib  # pylint: disable=relative-import


_BOT_FILE_MODE = 0o774  # permit owner group execution
_SYSTEMD_FILE_MODE = 0o644  # permit owner group write
_ROOT_USER = 'root'
# TODO(adrexler): Remove _DEVICEMAP_DIR once the arg is being passed from
# puppet.
_DEVICEMAP_DIR = os.path.dirname(os.path.realpath(__file__))
_STARTUP_SCRIPT_TEMPLATE_PATH = os.path.join(
    _DEVICEMAP_DIR, 'swarm_bot_startup.sh.template')
_STARTUP_SCRIPTS_PATH = 'startup_scripts'
_SWARM_BOT_PREFIX = 'swarming_bot--'
_SWARM_ZIP_RELATIVE_PATH_TO_BOT_HOME = '1/swarming_bot.zip'
_SYSTEMD_TEMPLATE_PATH = os.path.join(
    _DEVICEMAP_DIR, 'swarm_bot.systemd.template')
_DEPOT_TOOLS_DIR = os.path.join(os.path.expanduser('~'), 'depot_tools')


class OSException(Exception):
  """Exception class to handle OS Exceptions."""


def _GetNumBotConfigs(hostname):
  """Gets the number of bot configs assigned to the given hostname.

  Args:
    hostname: (String) Catatester hostame.

  Returns:
    An integer, The number of bot configs for given hostname.
  """
  logging.debug('Finding bots needed for host [%s]', hostname)
  configs = devicemap_lib.Configs()
  return configs.GetNumBotConfigs(hostname)


def CreateStartupScript(
    user, group, swarm_bots_home, bot_num, bot_name, gsutil_dir,
    gsutil_boto, fragglerock_key, eurtest_binaries, venv,
    devicemap_dir, depot_tools_dir):
  """Create the bot startup script.

  This method loads tokenized swarm_bot_startup.sh.template file, replaces the
  tokens with given param values and writes it into bot folder.

  Args:
    user: (String) User name of the catatester host.
    group: (String) Group name that is user is part of.
    swarm_bots_home: (String) Root directory of all the bots.
    bot_num: (Integer) The N-th bot to be created.
    bot_name: (String) Bot service name.
    gsutil_dir: (String) Path to gsutil installation in the host.
    gsutil_boto: (String) Path to gsutil boto file in the host.
    fragglerock_key: (String) Path to auth key file in the host.
    eurtest_binaries: (String) Path to test binaries in the host.
    venv: (String) Path to python virtual environment to be used.
    devicemap_dir: (String) Path to devicemap directory on host.
    depot_tools_dir: (String) Path to depot tools directory.

  Returns:
    The path of newly created startup script.
  """
  bot_dir_path = os.path.join(swarm_bots_home, str(bot_num))
  with open(_STARTUP_SCRIPT_TEMPLATE_PATH, 'r') as bot_startup:
    bot_startup_template = bot_startup.read()
  startup_script_content = string.Template(bot_startup_template).substitute(
      bot_dir=bot_dir_path,
      devicemap_dir=devicemap_dir,
      eurtest_binaries=eurtest_binaries,
      fragglerock_key=fragglerock_key,
      gsutil_dir=gsutil_dir,
      gsutil_boto=gsutil_boto,
      venv=venv,
      depot_tools_dir=depot_tools_dir
  )
  startup_script_path = os.path.join(swarm_bots_home, _STARTUP_SCRIPTS_PATH,
                                     '%s_startup.sh' % bot_name)
  _CreateFile(
      startup_script_path, startup_script_content, user, group, _BOT_FILE_MODE)
  return startup_script_path


def CreateSystemdServiceFile(
    bot_service_name, startup_script_path, user, group):
  """Create the systemd service script for a bot.

  This method loads tokenized swarm_bot.systemd.template file, replaces the
  tokens with given param values and writes it into systemd service folder.

  Args:
    bot_service_name: (String) The systemd service name to be used.
    startup_script_path: (String) Startup script path of the bot.
    user: (String) User name of the catatester host.
    group: (String) Group name that is user is part of.
  """
  with open(_SYSTEMD_TEMPLATE_PATH, 'r') as bot_systemd:
    bot_systemd_template = bot_systemd.read()
  systemd_service_content = string.Template(bot_systemd_template).substitute(
      bot_name=bot_service_name,
      group=group,
      user=user,
      startup_script_path=startup_script_path)
  systemd_service_path = '/etc/systemd/system/%s.service' % bot_service_name
  _CreateFile(
      systemd_service_path, systemd_service_content, _ROOT_USER, _ROOT_USER,
      _SYSTEMD_FILE_MODE)


def SetupBot(
    bot_num, user, group, swarm_bots_home, swarm_bot_prefix, swarm_zip_path,
    gsutil_dir, gsutil_boto, fragglerock_key, eurtest_binaries, venv,
    devicemap_dir, depot_tools_dir):
  """Setup the swarming bot.

  This method :
   1. Creates bot directory.
   2. Copies the swarm binary to bot directory.
   3. Creates start up scripts and systemd configs the bot.
   4. Do a systemd config reload.
   5. And finally start the bot service, if its not up.

  Args:
    bot_num: (Integer) The N-th bot to be created.
    user: (String) User name of the catatester host.
    group: (String) Group name that is user is part of.
    swarm_bots_home: (String) Root directory of the bots.
    swarm_bot_prefix: (String) Prefix to be used for bot service name.
    swarm_zip_path: (String) Swarming binary path in the host.
    gsutil_dir: (String) Path to gsutil installation in the host.
    gsutil_boto: (String) Path to gsutil boto file in the host.
    fragglerock_key: (String) Path to auth key file in the host.
    eurtest_binaries: (String) Path to test binaries in the host.
    venv: (String) Path to python virtual environment to be used.
    devicemap_dir: (String) Path to the device map directory.
    depot_tools_dir: (String) Path to depot tools directory.
  """
  logging.debug('Working on bot #%s', bot_num)
  # Create bot directory.
  bot_dir_path = os.path.join(swarm_bots_home, str(bot_num))
  if not os.path.exists(bot_dir_path):
    logging.info('Creating directory: %s', bot_dir_path)
    os.makedirs(bot_dir_path)
    _UpdateFilePermissions(bot_dir_path, user, group, _BOT_FILE_MODE)
  # Copy swarm binary
  if os.path.dirname(swarm_zip_path) != bot_dir_path:
    shutil.copy(swarm_zip_path, bot_dir_path)
    _UpdateFilePermissions(swarm_zip_path, user, group, _BOT_FILE_MODE)
  # Create startup scripts.
  bot_name = '%s%s' % (swarm_bot_prefix, bot_num)
  startup_script_path = CreateStartupScript(
      user, group, swarm_bots_home, bot_num, bot_name, gsutil_dir, gsutil_boto,
      fragglerock_key, eurtest_binaries, venv, devicemap_dir, depot_tools_dir)
  CreateSystemdServiceFile(bot_name, startup_script_path, user, group)
  # Reload the daemon, check bot status and start service if needed.
  if subprocess.call(['systemctl', 'daemon-reload']):
    sys.exit('Failed to reload systemctl daemon for bot # %s' % bot_num)
  if subprocess.call(['systemctl', 'is-active', '--quiet', bot_name]):
    logging.debug('Bot number [%s] not running. Starting now.', bot_num)
    if subprocess.call(['systemctl', 'start', bot_name]):
      sys.exit('Failed to start bot # %s' % bot_num)


def _UpdateFilePermissions(file_path, owner, group, mode):
  """Update file with specified mode and permissions."""
  uid = pwd.getpwnam(owner).pw_uid
  gid = grp.getgrnam(group).gr_gid
  os.chown(file_path, uid, gid)
  os.chmod(file_path, mode)


def _CreateFile(file_path, content, owner, group, mode):
  """Create file with specified content, mode and permissions."""
  if not os.path.exists(os.path.dirname(file_path)):
    try:
      os.makedirs(os.path.dirname(file_path))
      _UpdateFilePermissions(os.path.dirname(file_path), owner, group, mode)
    except OSError as exc:
      if exc.errno != errno.EEXIST:
        raise OSException('Unable to create dir %s due to %s.'
                          % (os.path.dirname(file_path), exc))

  with open(file_path, 'w') as f:
    f.write(content)
  _UpdateFilePermissions(file_path, owner, group, mode)


def _ParseArgs():
  """Parses command-line input."""
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--user', help='User name of the catatester host.', required=True)
  parser.add_argument('--group', help='Group name to be used.', required=True)
  parser.add_argument(
      '--swarm_bots_home', help='Root directory of the bots.', required=True)
  parser.add_argument(
      '--gsutil_dir', help='Path to gsutil installation.', required=True)
  parser.add_argument(
      '--gsutil_boto', help='Path to gs util boto file.', required=True)
  parser.add_argument(
      '--fragglerock_key', help='Path to fragglerock auth key file.',
      required=True)
  parser.add_argument(
      '--eurtest_binaries', help='Test binary path.', required=True)
  parser.add_argument(
      '--venv', help='Path to python to virtual environment.', required=True)
  parser.add_argument(
      '--devicemap_dir', help='Path to devicemap directory on the host.',
      default=_DEVICEMAP_DIR)
  parser.add_argument(
      '--depot_tools_dir', help='Path to depot_tools in the host.',
      default=_DEPOT_TOOLS_DIR)
  args = parser.parse_args()
  logging.debug('Executing with flags: %s', args)
  return args


def main():
  flags = _ParseArgs()
  bot_count = _GetNumBotConfigs(socket.gethostname().split('.')[0])
  swarm_bots_home = flags.swarm_bots_home
  swarm_zip_path = os.path.join(
      swarm_bots_home, _SWARM_ZIP_RELATIVE_PATH_TO_BOT_HOME)
  if not os.path.exists(swarm_zip_path):
    raise ValueError('Swarm binary does not exists at %s' % swarm_zip_path)
  for bot_num in range(1, bot_count +1):
    SetupBot(
        bot_num=bot_num, user=flags.user, group=flags.group,
        swarm_bots_home=swarm_bots_home, swarm_bot_prefix=_SWARM_BOT_PREFIX,
        swarm_zip_path=swarm_zip_path, gsutil_dir=flags.gsutil_dir,
        gsutil_boto=flags.gsutil_boto, fragglerock_key=flags.fragglerock_key,
        eurtest_binaries=flags.eurtest_binaries, venv=flags.venv,
        devicemap_dir=flags.devicemap_dir,
        depot_tools_dir=flags.depot_tools_dir)


if __name__ == '__main__':
  main()
