#!/usr/bin/python
# Copyright 2012 Google Inc. All Rights Reserved.
#
"""Run the given shell command for each of the given hosts."""

import os
import re
import select
import subprocess
import sys
import config
from portsh import options

__author__ = 'Avery Pennarun (apenwarr@google.com)'


optspec = """
run [options...] <hosts> -- <command string...>
--
r,raw           Raw output (don't prefix with the host's name)
q,quiet         Quiet: don't print to stderr for nonzero exit codes
"""


def _FixNull(s):
  if s is None:
    return ''
  return str(s)


def _ArgSub(argv, host):
  for arg in argv:
    argout = []
    for part in re.split(r'(\$\w+)', arg):
      if part.startswith('$'):
        for var in config.Host.__slots__:
          if part[1:] == var:
            part = _FixNull(getattr(host, var))
            break
      argout.append(part)
    yield ''.join(argout)


class Handler(object):
  def __init__(self, prefix, fileobj, raw):
    self.prefix = prefix
    self.fileobj = fileobj
    self.raw = raw

  def fileno(self):  #gpylint: disable-msg=C6409
    return self.fileobj.fileno()

  def Run(self):
    """Read from this handler and write its results to stdout."""
    buf = os.read(self.fileobj.fileno(), 65536)
    if buf:
      if self.raw:
        sys.stdout.write(buf)
      else:
        if not buf.endswith('\n'):
          buf += '\n'
        lines = buf.split('\n')[:-1]
        for line in lines:
          print '%s: %s' % (self.prefix, line)
    return buf


def main():
  o = options.Options(optspec)
  args = []
  cmd = []
  for i in range(1, len(sys.argv)):
    if sys.argv[i] == '--':
      args = sys.argv[1:i]
      cmd = sys.argv[i+1:]
      break
  opt, _, hostnames = o.parse(args)
  if not hostnames or not cmd:
    o.fatal('you must specify hosts, --, and a command string')

  try:
    hosts = [config.hosts.FindOne(name=i) for i in hostnames]
  except KeyError, e:
    o.fatal('host not configured: %s' % e)

  procs = []
  handlers = []
  for host in hosts:
    env = dict(os.environ)
    env.update(dict((key, _FixNull(getattr(host, key)))
                    for key in config.Host.__slots__))
    if len(cmd) > 1:
      argv = list(_ArgSub(cmd, host))
      shell = False
    else:
      argv = cmd[0]
      shell = True
    p = subprocess.Popen(argv, env=env, shell=shell,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    procs.append((host, p))
    handlers.append(Handler(host.name, p.stdout, opt.raw))
    handlers.append(Handler(host.name, p.stderr, opt.raw))

  while handlers:
    r, _, _ = select.select(handlers, [], [])
    for handler in r:
      if not handler.Run():
        handlers.remove(handler)

  final_rv = 0
  for host, p in procs:
    rv = p.wait()
    if rv != 0:
      if not opt.quiet:
        sys.stderr.write('-- %s: exited with error code %d\n'
                         % (host.name, rv))
      final_rv = 1
  return final_rv


if __name__ == '__main__':
  sys.exit(main())
