#!/usr/bin/python -u
# -*- coding: utf-8 -*-
#
# 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.

"""The main factory flow that runs the presenter-side of factory tests."""

import argparse
import logging
import syslog

import factory_common  # pylint: disable=W0611
from cros.factory.goofy import test_environment
from cros.factory.goofy.goofy_base import GoofyBase
from cros.factory.goofy.link_manager import DUTLinkManager
from cros.factory.goofy.ui_app_controller import UIAppController
from cros.factory.test import factory
from cros.factory.utils import jsonrpc_utils
from cros.factory.utils import sys_utils


class GoofyPresenter(GoofyBase):
  """Presenter side of Goofy.

  Note that all methods in this class must be invoked from the main
  (event) thread.  Other threads, such as callbacks and TestInvocation
  methods, should instead post events on the run queue.

  Properties:
    link_manager: The DUTLinkManager for this invocation of Goofy.
    ui_app_controller: UIAppController instance used to communicate with
        UI presenter app.
    dut_ips: The list of DUT ips.
    dut_dongle_mac_address: The dictionary maping the ip address of DUT to
        the dongle mac address of it.
  """

  def __init__(self):
    super(GoofyPresenter, self).__init__()

    self.args = self.ParseOptions()

    self.ui_app_controller = UIAppController(connect_hook=self.UIConnected)
    self.dut_ips = []
    self.dut_dongle_mac_address = {}

    if sys_utils.InCrOSDevice():
      self.env = test_environment.DUTEnvironment()
      self.env.has_sockets = self.ui_app_controller.HasWebSockets
    else:
      self.env = test_environment.FakeChrootEnvironment()
    self.env.launch_chrome()

    self.link_manager = DUTLinkManager(
        check_interval=1,
        connect_hook=self.DUTConnected,
        disconnect_hook=self.DUTDisconnected,
        methods={'StartCountdown': self.UIAppCountdown,
                 'UpdateStatus': self.UpdateStatus},
        standalone=self.args.standalone)

  def ParseOptions(self):
    parser = argparse.ArgumentParser(description='Run Goofy presenter')
    parser.add_argument('--standalone', action='store_true',
                        help=('Assume the controller is running on the same '
                              'machines.'))
    return parser.parse_args()

  def RetryShowUI(self):
    if not self.dut_ips:
      return
    dut_ip = self.dut_ips[-1]
    if self.ui_app_controller.ShowUI(dut_ip,
                                     self.dut_dongle_mac_address[dut_ip]):
      return
    # The UI is still not ready. Retry again.
    self.run_enqueue(self.RetryShowUI)

  def DUTConnected(self, dut_ip, dongle_mac_address):
    self.dut_dongle_mac_address[dut_ip] = dongle_mac_address
    self.dut_ips.append(dut_ip)
    # If the UI web server is ready, show it.
    if self.ui_app_controller.ShowUI(dut_ip, dongle_mac_address):
      return
    # Well, it's probably not. Let's schedule a retry.
    self.run_enqueue(self.RetryShowUI)

  def DUTDisconnected(self, dut_ip):
    dongle_mac_address = self.dut_dongle_mac_address[dut_ip]
    self.ui_app_controller.ShowDisconnectedScreen(dongle_mac_address)
    self.dut_ips.remove(dut_ip)
    del self.dut_dongle_mac_address[dut_ip]

  def UIConnected(self):
    if self.dut_ips:
      dut_ip = self.dut_ips[-1]
      self.ui_app_controller.ShowUI(dut_ip, self.dut_dongle_mac_address[dut_ip])

  def UIAppCountdown(self, message, timeout_secs, timeout_message,
                     timeout_message_color):
    """Start countdown on the UI.

    Args:
      message: The text to show during countdown.
      timeout_secs: The timeout for countdown.
      timeout_message: The text to show when countdown eneds.
      timeout_message_color: The color of the text when countdown ends.
    """
    dut_ip = jsonrpc_utils.GetJSONRPCCallerIP()
    dongle_mac_address = self.dut_dongle_mac_address[dut_ip]
    self.ui_app_controller.StartCountdown(message,
                                          dongle_mac_address,
                                          timeout_secs,
                                          timeout_message,
                                          timeout_message_color)

  def UpdateStatus(self, all_pass):
    dut_ip = jsonrpc_utils.GetJSONRPCCallerIP()
    dongle_mac_address = self.dut_dongle_mac_address[dut_ip]
    self.ui_app_controller.UpdateStatus(dongle_mac_address, all_pass)

  def main(self):
    """Entry point for goofy_presenter instance."""
    syslog.openlog('goofy_presenter')
    syslog.syslog('GoofyPresenter (factory test harness) starting')
    self.link_manager.Start()
    self.run()

  def destroy(self):
    """Performs any shutdown tasks. Overrides base class method."""
    self.link_manager.Stop()
    self.ui_app_controller.Stop()
    super(GoofyPresenter, self).destroy()
    logging.info('Done destroying GoofyPresenter')


if __name__ == '__main__':
  factory.init_logging()
  GoofyPresenter.run_main_and_exit()
