#!/usr/bin/python
# Copyright 2012 Google Inc. All Rights Reserved.
#
"""A command-line tool for uploading to gfiber-dropbox.appspot.com."""

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

import errno
import os
import re
import subprocess
import sys
import options


optspec = """
upload-crash-log [options...]
--
s,server=          The server URL (default: whatever upload-logs uses)
a,all              Upload the entire log, not just the most recent part
l,logtype=         The logtype to send to the server
stdout             Print to stdout instead of calling upload-logs
"""

MARK_START = '*LOG_UPLOAD_START*'
MARK_END = '*LOG_UPLOAD_END*'


class SubprocError(Exception):
  pass


def ReadPipe(argv, **kwargs):
  p = subprocess.Popen(argv, stdout=subprocess.PIPE, **kwargs)
  data = p.stdout.read()
  retval = p.wait()
  if retval:
    raise SubprocError('%r returned exit code %d' % (argv, retval))
  return data


def TryReadPipe(argv, **kwargs):
  try:
    return ReadPipe(argv, **kwargs)
  except SubprocError:
    return ''
  except OSError, e:
    if e.errno == errno.ENOENT:
      return ''
    else:
      raise


def ReFind(regex, key, data):
  matches = re.findall(regex, data)
  return ['%s=%s' % (key, i) for i in matches]


def IfconfigData(ifcname):
  """Returns a list of key/value pairs for the given network interface."""
  data = TryReadPipe(['ip', 'addr', 'show', ifcname])
  out = []
  out += ReFind(r'inet ([\d.]+/\d+)', 'ip', data)
  out += ReFind(r'inet6 ([\da-fA-F:/.]+/\d+)', 'ip6', data)
  out += ReFind(r'link/ether ([\da-fA-F:]+)', 'hw', data)
  return out


def NvramData():
  """Returns a list of key/value pairs based on NVRAM contents."""
  return ['serial=' + TryReadPipe(['/bin/serial']).rstrip()]


def ModelName():
  try:
    model = open('/etc/platform').read().rstrip()
    return ['model=' + model]
  except IOError:
    return None


def Marker(s):
  """Print the given marker string to the dmesg log."""
  open('/dev/kmsg', 'w').write('<7>%s\n' % s)


def UploadLog(server, filename, content, keys):
  """Upload a log file to the given server by calling upload-logs."""
  extra_args = []
  if server:
    extra_args += ['--server', server]
  p = subprocess.Popen(['upload-logs', '--stdin', filename] +
                       extra_args +
                       ['-k%s' % i for i in keys],
                       stdin=subprocess.PIPE)
  p.stdin.write(content)
  p.stdin.close()
  retval = p.wait()
  if retval:
    raise Exception('upload-logs returned exit code %d' % retval)


def FirstStamp(s):
  regex = re.compile(r'^(<[0-9]+>)?\[\s*([0-9.]+\.[0-9]+)\s*\]', re.M)
  g = re.search(regex, s)
  if g:
    return float(g.group(2))
  return None


def main():
  o = options.Options(optspec)
  (opt, flags, extra) = o.parse(sys.argv[1:])  # pylint: disable-msg=W0612
  if extra:
    o.fatal('no filenames expected')

  subprocess.call('logmark-once')
  Marker(MARK_START)

  # In case the system crashes after we finish uploading but before the next
  # time this script runs, we want to make sure there's at least one logmark
  # in the *next* segment as well.  Otherwise the server won't be able to
  # feel certain about what version that segment came from.  So add it again
  # now.
  subprocess.call('logmark-once')

  p = subprocess.Popen(['toolbox', 'dmesg'], stdout=subprocess.PIPE)
  dmesg = p.stdout.read()
  retval = p.wait()
  if retval:
    raise Exception('dmesg returned exit code %d' % retval)

  interfaces = set(['br0', 'eth0', 'man', 'pon0'])
  interfaces = interfaces.intersection(os.listdir('/sys/class/net'))
  keys = []
  for iface in interfaces:
    keys += IfconfigData(iface)
  model = ModelName()
  if model:
    keys += model
  if opt.logtype:
    keys.append('logtype=' + opt.logtype)
  keys = set(keys + NvramData())
  os.environ['PATH'] += ':.'  # make sure PWD is searched for upload-logs

  if not opt.all:
    # we only want the text from after the last MARK_START that came *before*
    # the last MARK_END.  If we tried uploading previously but failed, it
    # will have printed a MARK_START but not a MARK_END, and we have to ignore
    # that one and retry.  However, we can't just use MARK_END, because
    # messages might have been printed after retrieving the dmesg text
    # but before printing MARK_END.
    #
    # And we don't want anything that came after the final MARK_START, because
    # that will be uploaded next time, and we don't want duplicate data.
    start = dmesg.rfind(MARK_END)
    if start < 0: start = 0
    start = dmesg.rfind(MARK_START, 0, start)
    if start < 0: start = 0
    end = dmesg.rfind(MARK_START)
    if end < 0:
      end = len(dmesg)
    dmesg = dmesg[start:end]
    if start == 0 and FirstStamp(dmesg) != 0.0:
      dmesg = ('\n\nWARNING: log buffer overflow.  '
               'Some messages were lost at this position.\n\n' +
               dmesg)

  if opt.stdout:
    print dmesg
  else:
    UploadLog(opt.server, 'dmesg', dmesg, keys)

  Marker(MARK_END)

if __name__ == '__main__':
  main()
