# Copyright (c) 2014 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.

"""This module launches the cherrypy server for webplot and sets up
web sockets to handle the messages between the clients and the server.
"""

import argparse
import json
import logging
import os
import re
import subprocess
import threading

import cherrypy

import remote

from ws4py import configure_logger
from ws4py.messaging import TextMessage
from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
from ws4py.websocket import WebSocket

from remote.remote import ChromeOSTouchDevice, AndroidTouchDevice


# The WebSocket connection state object.
state = None

# The touch events are saved in this file as default.
SAVED_FILE = '/tmp/webplot.dat'


class WebplotWSHandler(WebSocket):
  """The web socket handler for webplot."""

  def opened(self):
    """This method is called when the handler is opened."""
    cherrypy.log('WS handler is opened!')

  def received_message(self, msg):
    """A callback for received message."""
    cherrypy.log('Received message: %s' % str(msg.data))
    if msg.data.lower() == 'quit':
      # A shutdown message.
      cherrypy.log('The user requests to shutdown the cherrypy server....')
      state.DecCount()
    else:
      # A save message.
      #   E.g. 'save:/tmp/webplot.dat'
      data = msg.data.split(':')
      if len(data) == 2:
        mtype, content = data
        if mtype.lower() == 'save':
          cherrypy.log('Save data to %s' % content)

  def closed(self, code, reason="A client left the room."):
    """This method is called when the handler is closed."""
    cherrypy.log('A client requests to close WS.')
    cherrypy.engine.publish('websocket-broadcast', TextMessage(reason))


class TouchDeviceWrapper(object):
  """This is a wrapper of remote.RemoteTouchDevice.

  It handles the instantiation of different device types, and the beginning
  and ending of the event stream.
  """

  def __init__(self, dut_type, addr, is_touchscreen):
    if dut_type == 'chromeos':
      self.device = ChromeOSTouchDevice(addr, is_touchscreen)
    else:
      self.device = AndroidTouchDevice(addr, True)
    self.device.BeginEventStream()

  def __del__(self):
    self.device.EndEventStream()

  def __str__(self):
    return '\n  '.join(sorted([str(slot) for slot in self.slots.values()]))


def ThreadedGetLiveStreamSnapshots(device, saved_file):
  """A thread to poll and get live stream snapshots continuously."""

  def _ConvertNamedtupleToDict(snapshot, leaving_slots):
    """Convert namedtuples to ordinary dictionaries and add leaving slots.

    This is to make a snapshot json serializable. Otherwise, the namedtuples
    would be transmitted as arrays which is less readable.

    A snapshot looks like
      MtbSnapshot(
          syn_time=1420524008.368854,
          button_pressed=False,
          fingers=[
              MtbFinger(tid=162, slot=0, syn_time=1420524008.368854, x=524,
                        y=231, pressure=45),
              MtbFinger(tid=163, slot=1, syn_time=1420524008.368854, x=677,
                        y=135, pressure=57)
          ]
      )

    Note:
    1. that there are two levels of namedtuples to convert.
    2. The leaving slots are used to notify javascript that a finger is leaving
       so that the corresponding finger color could be released for reuse.
    """
    # Convert MtbSnapshot.
    converted = dict(snapshot.__dict__.items())

    # Convert MtbFinger.
    converted['fingers'] = [dict(finger.__dict__.items())
                            for finger in converted['fingers']]

    # Add leaving attribute.
    for finger in converted['fingers']:
      finger['leaving'] = bool(finger['slot'] in leaving_slots)

    return converted

  def _GetLiveStreamSnapshots():
    """Get live stream snapshots."""
    cherrypy.log('Start getting the live stream snapshots....')
    snapshot_stream = remote.mtb.SnapshotStream(device.device)
    with open(saved_file, 'w') as f:
      while True:
        snapshot, events, leaving_slots = snapshot_stream.Get()
        if snapshot:
          f.write('\n'.join(events) + '\n')
          f.flush()
          snapshot = _ConvertNamedtupleToDict(snapshot, leaving_slots)
          cherrypy.engine.publish('websocket-broadcast', json.dumps(snapshot))

  get_snapshot_thread = threading.Thread(target=_GetLiveStreamSnapshots,
                                         name='_GetLiveStreamSnapshots')
  get_snapshot_thread.daemon = True
  get_snapshot_thread.start()


class ConnectionState(object):
  """A ws connection state object for shutting down the cherrypy server.

  It shuts down the cherrypy server when the count is down to 0 and is not
  increased before the shutdown_timer expires.

  Note that when a page refreshes, it closes the WS connection first and
  then re-connects immediately. This is why we would like to wait a while
  before actually shutting down the server.
  """
  TIMEOUT = 1.0

  def __init__(self):
    self.count = 0;
    self.lock = threading.Lock()
    self.shutdown_timer = None

  def IncCount(self):
    """Increase the connection count, and cancel the shutdown timer if exists.
    """
    self.lock.acquire()
    self.count += 1;
    cherrypy.log('  WS connection count: %d' % self.count)
    if self.shutdown_timer:
      self.shutdown_timer.cancel()
      self.shutdown_timer = None
    self.lock.release()

  def DecCount(self):
    """Decrease the connection count, and start a shutdown timer if no other
    clients are connecting to the server.
    """
    self.lock.acquire()
    self.count -= 1;
    cherrypy.log('  WS connection count: %d' % self.count)
    if self.count == 0:
      self.shutdown_timer = threading.Timer(self.TIMEOUT, self.Shutdown)
      self.shutdown_timer.start()
    self.lock.release()

  def Shutdown(self):
    """Shutdown the cherrypy server."""
    cherrypy.log('Shutdown timer expires. Cherrypy server for Webplot exits.')
    cherrypy.engine.exit()


class Root(object):
  """A class to handle requests about docroot."""

  def __init__(self, ip, port, touch_max_x, touch_max_y):
    self.ip = ip
    self.port = port
    self.touch_max_x = touch_max_x
    self.touch_max_y = touch_max_y
    self.scheme = 'ws'
    cherrypy.log('Root address: (%s, %s)' % (ip, str(port)))
    cherrypy.log('scheme: %s' % self.scheme)

  @cherrypy.expose
  def index(self):
    """This is the default index.html page."""
    websocket_dict = {
      'websocketUrl': '%s://%s:%s/ws' % (self.scheme, self.ip, self.port),
      'touchMaxX': str(self.touch_max_x),
      'touchMaxY': str(self.touch_max_y),
    }
    root_page = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                             'webplot.html')
    with open(root_page) as f:
      return f.read() % websocket_dict

  @cherrypy.expose
  def ws(self):
    """This handles the request to create a new web socket per client."""
    cherrypy.log('A new client requesting for WS')
    cherrypy.log('WS handler created: %s' % repr(cherrypy.request.ws_handler))
    state.IncCount()


def SimpleSystem(cmd):
  """Execute a system command."""
  ret = subprocess.call(cmd, shell=True)
  if ret:
    logging.warning('Command (%s) failed (ret=%s).', cmd, ret)
  return ret


def SimpleSystemOutput(cmd):
  """Execute a system command and get its output."""
  try:
    proc = subprocess.Popen(
        cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stdout, _ = proc.communicate()
  except Exception, e:
    logging.warning('Command (%s) failed (%s).', cmd, e)
  else:
    return None if proc.returncode else stdout.strip()


def IsDestinationPortEnabled(port):
  """Check if the destination port is enabled in iptables.

  If port 8000 is enabled, it looks like
    ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  ctstate NEW tcp dpt:8000
  """
  pattern = re.compile('ACCEPT\s+tcp.+\s+ctstate\s+NEW\s+tcp\s+dpt:%d' % port)
  rules = SimpleSystemOutput('iptables -L INPUT -n --line-number')
  for rule in rules.splitlines():
    if pattern.search(rule):
      return True
  return False


def EnableDestinationPort(port):
  """Enable the destination port for input traffic in iptables."""
  if IsDestinationPortEnabled(port):
    cherrypy.log('Port %d has been already enabled in iptables.' % port)
  else:
    cherrypy.log('To enable port %d in iptables.' % port)
    cmd = ('iptables -A INPUT -p tcp -m conntrack --ctstate NEW --dport %d '
           '-j ACCEPT' % port)
    if SimpleSystem(cmd) != 0:
      raise Error('Failed to enable port in iptables: %d.' % port)


def _ParseArguments():
  """Parse the command line options."""
  parser = argparse.ArgumentParser(description='Webplot Server')
  parser.add_argument('-a', '--dut_addr', default='localhost',
                      help='the address of the dut')
  parser.add_argument('-p', '--server_port', default=80, type=int,
                      help='the port the web server to listen to (default: 80)')
  parser.add_argument('--is_touchscreen', help='the DUT is touchscreen',
                      action='store_true')
  parser.add_argument('-t', '--dut_type', default='chromeos',
                      help='dut type: chromeos, android')
  args = parser.parse_args()
  return args


def Main():
  """The main function to launch webplot service."""
  global state

  configure_logger(level=logging.DEBUG)
  args = _ParseArguments()

  print '\n' + '-' * 70
  cherrypy.log('dut type: %s' % args.dut_type)
  cherrypy.log('dut address: %s' % args.dut_addr)
  cherrypy.log('dut\'s touch device: %s' %
               ('touchscreen' if args.is_touchscreen else 'touchpad'))
  cherrypy.log('web server port: %s' % args.server_port)
  cherrypy.log('touch events are saved in %s' % SAVED_FILE)
  if args.dut_addr == 'localhost':
    addr = (args.dut_addr if args.server_port == 80 else
            '%s:%s' % (args.dut_addr, args.server_port))
    msg = '****** Type "%s" in browser to see finger traces.'
    cherrypy.log(msg % addr)
  print '-' * 70 + '\n\n'

  # Allow input traffic in iptables.
  EnableDestinationPort(args.server_port)

  # Instantiate a touch device.
  device = TouchDeviceWrapper(args.dut_type, args.dut_addr, args.is_touchscreen)

  # Start to get touch snapshots from the specified touch device.
  ThreadedGetLiveStreamSnapshots(device, SAVED_FILE)

  # Create a ws connection state object to wait for the condition to
  # shutdown the whole process.
  state = ConnectionState()

  cherrypy.config.update({
    'server.socket_host': args.dut_addr,
    'server.socket_port': args.server_port,
  })

  WebSocketPlugin(cherrypy.engine).subscribe()
  cherrypy.tools.websocket = WebSocketTool()

  touch_max_x = device.device.width
  touch_max_y = device.device.height
  cherrypy.quickstart(
    Root(args.dut_addr, args.server_port, touch_max_x, touch_max_y), '',
         config={
           '/': {
             'tools.staticdir.root': os.path.abspath(os.path.dirname(__file__)),
             'tools.staticdir.on': True,
             'tools.staticdir.dir': '',
           },
           '/ws': {
             'tools.websocket.on': True,
             'tools.websocket.handler_cls': WebplotWSHandler,
           },
         }
  )


if __name__ == '__main__':
  Main()
