#!/usr/bin/env python3
# Copyright 2017 The Emscripten Authors.  All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License.  Both these licenses can be
# found in the LICENSE file.

"""emrun: Implements machinery that allows running a .html page as if it was a
standard executable file.

Usage: emrun <options> filename.html <args to program>

See emrun --help for more information
"""

# N.B. Do not introduce external dependencies to this file. It is often used
# standalone outside Emscripten directory tree.
import argparse
import atexit
import cgi
import json
import os
import platform
import re
import shlex
import shutil
import socket
import stat
import struct
import subprocess
import sys
import tempfile
import threading
import time
from operator import itemgetter

if sys.version_info.major == 2:
  import SocketServer as socketserver
  from BaseHTTPServer import HTTPServer
  from SimpleHTTPServer import SimpleHTTPRequestHandler
  from urllib import unquote
  from urlparse import urlsplit

  def print_to_handle(handle, line):
    print >> handle, line # noqa: F633
else:
  import socketserver
  from http.server import HTTPServer, SimpleHTTPRequestHandler
  from urllib.parse import unquote, urlsplit

  def print_to_handle(handle, line):
    handle.write(line + '\n')

# Populated from cmdline params
emrun_options = None

# Represents the process object handle to the browser we opened to run the html
# page.
browser_process = None

previous_browser_processes = None
current_browser_processes = None

navigation_has_occurred = False

# Stores the browser executable that was run with --browser= parameter.
browser_exe = None

# If we have routed browser output to file with --log_stdout and/or
# --log_stderr, these track the handles.
browser_stdout_handle = sys.stdout
browser_stderr_handle = sys.stderr

# This flag tracks whether the html page has sent any stdout messages back to
# us.  Used to detect whether we might have gotten detached from the browser
# process we spawned, in which case we are not able to detect when user closes
# the browser with the close button.
have_received_messages = False

# At startup print a warning message once if user did not build with --emrun.
emrun_not_enabled_nag_printed = False

# Stores the exit() code of the html page when/if it quits.
page_exit_code = None

# If this is set to a non-empty string, all processes by this name will be
# killed at exit.  This is used to clean up after browsers that spawn
# subprocesses to handle the actual browser launch. For example opera has a
# launcher.exe that runs the actual opera browser.  So killing browser_process
# would just kill launcher.exe and not the opera
# browser itself.
processname_killed_atexit = ""

# Using "0.0.0.0" means "all interfaces", which should allow connecting to this
# server via LAN addresses. Using "localhost" should allow only connecting from
# local computer.
default_webserver_hostname = '0.0.0.0'

# If user does not specify a --port parameter, this port is used to launch the
# server.
default_webserver_port = 6931

# Location of Android Debug Bridge executable
ADB = None

# Host OS detection to autolocate browsers and other OS-specific support needs.
WINDOWS = False
LINUX = False
MACOS = False
if os.name == 'nt':
  WINDOWS = True
  import winreg
elif platform.system() == 'Linux':
  LINUX = True
elif platform.mac_ver()[0] != '':
  MACOS = True
  import plistlib

# If you are running on an OS that is not any of these, must add explicit support for it.
if not WINDOWS and not LINUX and not MACOS:
  raise Exception("Unknown OS!")


# Returns wallclock time in seconds.
def tick():
  # Would like to return time.clock() since it's apparently better for
  # precision, but it is broken on macOS 10.10 and Python 2.7.8.
  return time.time()


# Absolute wallclock time in seconds specifying when the previous HTTP stdout
# message from the page was received.
last_message_time = tick()

# Absolute wallclock time in seconds telling when we launched emrun.
page_start_time = tick()

# Stores the time of most recent http page serve.
page_last_served_time = None


def format_html(msg):
  """Returns given log message formatted to be outputted on a HTML page."""
  if not msg.endswith('\n'):
    msg += '\n'
  msg = cgi.escape(msg)
  msg = msg.replace('\r\n', '<br />').replace('\n', '<br />')
  return msg


# HTTP requests are handled from separate threads - synchronize them to avoid race conditions
http_mutex = threading.RLock()


def logi(msg):
  """Prints a log message to 'info' stdout channel. Always printed.
  """
  global last_message_time
  with http_mutex:
    if emrun_options.log_html:
      sys.stdout.write(format_html(msg))
    else:
      print_to_handle(sys.stdout, msg)
    sys.stdout.flush()
    last_message_time = tick()


def logv(msg):
  """Prints a verbose log message to stdout channel.
  Only shown if run with --verbose.
  """
  global last_message_time
  if emrun_options.verbose:
    with http_mutex:
      if emrun_options.log_html:
        sys.stdout.write(format_html(msg))
      else:
        print_to_handle(sys.stdout, msg)
      sys.stdout.flush()
      last_message_time = tick()


def loge(msg):
  """Prints an error message to stderr channel.
  """
  global last_message_time
  with http_mutex:
    if emrun_options.log_html:
      sys.stderr.write(format_html(msg))
    else:
      print_to_handle(sys.stderr, msg)
    sys.stderr.flush()
    last_message_time = tick()


def format_eol(msg):
  if WINDOWS:
    msg = msg.replace('\r\n', '\n').replace('\n', '\r\n')
  return msg


def browser_logi(msg):
  """Prints a message to the browser stdout output stream.
  """
  global last_message_time
  msg = format_eol(msg)
  print_to_handle(browser_stdout_handle, msg)
  browser_stdout_handle.flush()
  last_message_time = tick()


def browser_loge(msg):
  """Prints a message to the browser stderr output stream.
  """
  global last_message_time
  msg = format_eol(msg)
  print_to_handle(browser_stderr_handle, msg)
  browser_stderr_handle.flush()
  last_message_time = tick()


def unquote_u(source):
  """Unquotes a unicode string.
  (translates ascii-encoded utf string back to utf)
  """
  result = unquote(source)
  if '%u' in result:
    result = result.replace('%u', '\\u').decode('unicode_escape')
  return result


temp_firefox_profile_dir = None


def delete_emrun_safe_firefox_profile():
  """Deletes the temporary created Firefox profile (if one exists)"""
  global temp_firefox_profile_dir
  if temp_firefox_profile_dir is not None:
    logv('remove_tree("' + temp_firefox_profile_dir + '")')
    remove_tree(temp_firefox_profile_dir)
    temp_firefox_profile_dir = None


# Firefox has a lot of default behavior that makes it unsuitable for
# automated/unattended run.
# This function creates a temporary profile directory that customized Firefox
# with various flags that enable automated runs.
def create_emrun_safe_firefox_profile():
  global temp_firefox_profile_dir
  temp_firefox_profile_dir = tempfile.mkdtemp(prefix='temp_emrun_firefox_profile_')
  with open(os.path.join(temp_firefox_profile_dir, 'prefs.js'), 'w') as f:
    f.write('''
// Lift the default max 20 workers limit to something higher to avoid hangs when page needs to spawn a lot of threads.
user_pref("dom.workers.maxPerDomain", 100);
// Always allow opening popups
user_pref("browser.popups.showPopupBlocker", false);
user_pref("dom.disable_open_during_load", false);
// Don't ask user if they want to set Firefox as the default system browser
user_pref("browser.shell.checkDefaultBrowser", false);
user_pref("browser.shell.skipDefaultBrowserCheck", true);
// If automated runs crash, don't resume old tabs on the next run or show safe mode dialogs or anything else extra.
user_pref("browser.sessionstore.resume_from_crash", false);
user_pref("services.sync.prefs.sync.browser.sessionstore.restore_on_demand", false);
user_pref("browser.sessionstore.restore_on_demand", false);
user_pref("browser.sessionstore.max_resumed_crashes", -1);
user_pref("toolkit.startup.max_resumed_crashes", -1);
// Don't show the slow script dialog popup
user_pref("dom.max_script_run_time", 0);
user_pref("dom.max_chrome_script_run_time", 0);
// Don't open a home page at startup
user_pref("startup.homepage_override_url", "about:blank");
user_pref("startup.homepage_welcome_url", "about:blank");
user_pref("browser.startup.homepage", "about:blank");
// Don't try to perform browser (auto)update on the background
user_pref("app.update.auto", false);
user_pref("app.update.enabled", false);
user_pref("app.update.silent", false);
user_pref("app.update.mode", 0);
user_pref("app.update.service.enabled", false);
// Don't check compatibility with add-ons, or (auto)update them
user_pref("extensions.lastAppVersion", '');
user_pref("plugins.hide_infobar_for_outdated_plugin", true);
user_pref("plugins.update.url", '');
// Disable health reporter
user_pref("datareporting.healthreport.service.enabled", false);
// Disable crash reporter
user_pref("toolkit.crashreporter.enabled", false);
// Don't show WhatsNew on first run after every update
user_pref("browser.startup.homepage_override.mstone","ignore");
// Don't show 'know your rights' and a bunch of other nag windows at startup
user_pref("browser.rights.3.shown", true);
user_pref('devtools.devedition.promo.shown', true);
user_pref('extensions.shownSelectionUI', true);
user_pref('browser.newtabpage.introShown', true);
user_pref('browser.download.panel.shown', true);
user_pref('browser.customizemode.tip0.shown', true);
user_pref("browser.toolbarbuttons.introduced.pocket-button", true);
// Don't ask the user if they want to close the browser when there are multiple tabs.
user_pref("browser.tabs.warnOnClose", false);
// Allow the launched script window to close itself, so that we don't need to kill the browser process in order to move on.
user_pref("dom.allow_scripts_to_close_windows", true);
// Set various update timers to a large value in the future in order to not
// trigger a large mass of update HTTP traffic on each Firefox run on the clean profile.
// 2147483647 seconds since Unix epoch is sometime in the year 2038, and this is the max integer accepted by Firefox.
user_pref("app.update.lastUpdateTime.addon-background-update-timer", 2147483647);
user_pref("app.update.lastUpdateTime.background-update-timer", 2147483647);
user_pref("app.update.lastUpdateTime.blocklist-background-update-timer", 2147483647);
user_pref("app.update.lastUpdateTime.browser-cleanup-thumbnails", 2147483647);
user_pref("app.update.lastUpdateTime.experiments-update-timer", 2147483647);
user_pref("app.update.lastUpdateTime.search-engine-update-timer", 2147483647);
user_pref("app.update.lastUpdateTime.xpi-signature-verification", 2147483647);
user_pref("extensions.getAddons.cache.lastUpdate", 2147483647);
user_pref("media.gmp-eme-adobe.lastUpdate", 2147483647);
user_pref("media.gmp-gmpopenh264.lastUpdate", 2147483647);
user_pref("datareporting.healthreport.nextDataSubmissionTime", "2147483647000");
// Sending Firefox Health Report Telemetry data is not desirable, since these are automated runs.
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("datareporting.healthreport.service.enabled", false);
user_pref("datareporting.healthreport.service.firstRun", false);
user_pref("toolkit.telemetry.enabled", false);
user_pref("toolkit.telemetry.unified", false);
user_pref("datareporting.policy.dataSubmissionEnabled", false);
user_pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);
// Allow window.dump() to print directly to console
user_pref("browser.dom.window.dump.enabled", true);
// Disable background add-ons related update & information check pings
user_pref("extensions.update.enabled", false);
user_pref("extensions.getAddons.cache.enabled", false);
// Enable wasm
user_pref("javascript.options.wasm", true);
// Enable SharedArrayBuffer (this profile is for a testing environment, so Spectre/Meltdown don't apply)
user_pref("javascript.options.shared_memory", true);
''')
    if emrun_options.private_browsing:
      f.write('''
// Start in private browsing mode to not cache anything to disk (everything will be wiped anyway after this run)
user_pref("browser.privatebrowsing.autostart", true);
      ''')
  logv('create_emrun_safe_firefox_profile: Created new Firefox profile "' + temp_firefox_profile_dir + '"')
  return temp_firefox_profile_dir


def is_browser_process_alive():
  """Returns whether the browser page we spawned is still running.
  (note, not perfect atm, in case we are running in detached mode)
  """
  # If navigation to the web page has not yet occurred, we behave as if the
  # browser has not yet even loaded the page, and treat it as if the browser
  # is running (as it is just starting up)
  if not navigation_has_occurred:
    return True

  if browser_process and browser_process.poll() is None:
    return True

  if current_browser_processes:
    try:
      import psutil
      for p in current_browser_processes:
        if psutil.pid_exists(p['pid']):
          return True
      return False
    except Exception:
      # Fail gracefully if psutil not available
      logv('psutil is not available, emrun may not be able to accurately track whether the browser process is alive or not')

  # We do not have a track of the browser process ID that we spawned.
  # Make an assumption that the browser process is open as long until
  # the C program calls exit().
  return page_exit_code is None


def kill_browser_process():
  """Kills browser_process and processname_killed_atexit. Also removes the
  temporary Firefox profile that was created, if one exists.
  """
  global browser_process, processname_killed_atexit, current_browser_processes
  if browser_process and browser_process.poll() is None:
    try:
      logv('Terminating browser process pid=' + str(browser_process.pid) + '..')
      browser_process.kill()
    except Exception as e:
      logv('Failed with error ' + str(e) + '!')

    browser_process = None
    # We have a hold of the target browser process explicitly, no need to resort to killall,
    # so clear that record out.
    processname_killed_atexit = ''

  if current_browser_processes:
    for pid in current_browser_processes:
      try:
        logv('Terminating browser process pid=' + str(pid['pid']) + '..')
        os.kill(pid['pid'], 9)
      except Exception as e:
        logv('Failed with error ' + str(e) + '!')

    current_browser_processes = None
    # We have a hold of the target browser process explicitly, no need to resort to killall,
    # so clear that record out.
    processname_killed_atexit = ''

  if len(processname_killed_atexit):
    if emrun_options.android:
      logv("Terminating Android app '" + processname_killed_atexit + "'.")
      subprocess.call([ADB, 'shell', 'am', 'force-stop', processname_killed_atexit])
    else:
      logv("Terminating all processes that have string '" + processname_killed_atexit + "' in their name.")
      if WINDOWS:
        process_image = processname_killed_atexit if '.exe' in processname_killed_atexit else (processname_killed_atexit + '.exe')
        process = subprocess.Popen(['taskkill', '/F', '/IM', process_image, '/T'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.communicate()
      else:
        try:
          subprocess.call(['pkill', processname_killed_atexit])
        except OSError:
          try:
            subprocess.call(['killall', processname_killed_atexit])
          except OSError:
            loge('Both commands pkill and killall failed to clean up the spawned browser process. Perhaps neither of these utilities is available on your system?')
      delete_emrun_safe_firefox_profile()
    # Clear the process name to represent that the browser is now dead.
    processname_killed_atexit = ''

  delete_emrun_safe_firefox_profile()


# Heuristic that attempts to search for the browser process IDs that emrun spawned.
# This depends on the assumption that no other browser process IDs have been spawned
# during the short time perioed between the time that emrun started, and the browser
# process navigated to the page.
# This heuristic is needed because all modern browsers are multiprocess systems -
# starting a browser process from command line generally launches just a "stub" spawner
# process that immediately exits.
def detect_browser_processes():
  if not browser_exe:
    return # Running with --no_browser, we are not binding to a spawned browser.

  global current_browser_processes
  logv('First navigation occurred. Identifying currently running browser processes')
  running_browser_processes = list_processes_by_name(browser_exe)

  def pid_existed(pid):
    for proc in previous_browser_processes:
      if proc['pid'] == pid:
        return True
    return False

  for p in running_browser_processes:
    logv('Detected running browser process id: ' + str(p['pid']) + ', existed already at emrun startup? ' + str(pid_existed(p['pid'])))

  current_browser_processes = [p for p in running_browser_processes if not pid_existed(p['pid'])]

  if len(current_browser_processes) == 0:
    logv('Was unable to detect the browser process that was spawned by emrun. This may occur if the target page was opened in a tab on a browser process that already existed before emrun started up.')


# Our custom HTTP web server that will server the target page to run via .html.
# This is used so that we can load the page via a http:// URL instead of a
# file:// URL, since those wouldn't work too well unless user allowed XHR
# without CORS rules.  Also, the target page will route its stdout and stderr
# back to here via HTTP requests.
class HTTPWebServer(socketserver.ThreadingMixIn, HTTPServer):
  """Log messaging arriving via HTTP can come in out of sequence. Implement a
  sequencing mechanism to enforce ordered transmission."""
  expected_http_seq_num = 1
  # Stores messages that have arrived out of order, pending for a send as soon
  # as the missing message arrives.  Kept in sorted order, first element is the
  # oldest message received.
  http_message_queue = []

  def handle_incoming_message(self, seq_num, log, data):
    global have_received_messages
    with http_mutex:
      have_received_messages = True

      if seq_num == -1:
        # Message arrived without a sequence number? Just log immediately
        log(data)
      elif seq_num == self.expected_http_seq_num:
        log(data)
        self.expected_http_seq_num += 1
        self.print_messages_due()
      elif seq_num < self.expected_http_seq_num:
        log(data)
      else:
        self.http_message_queue += [(seq_num, data, log)]
        self.http_message_queue.sort(key=itemgetter(0))
        if len(self.http_message_queue) > 16:
          self.print_next_message()

  # If it's been too long since we we got a message, prints out the oldest
  # queued message, ignoring the proper order.  This ensures that if any
  # messages are actually lost, that the message queue will be orderly flushed.
  def print_timed_out_messages(self):
    global last_message_time
    with http_mutex:
      now = tick()
      max_message_queue_time = 5
      if len(self.http_message_queue) and now - last_message_time > max_message_queue_time:
        self.print_next_message()

  # Skips to printing the next message in queue now, independent of whether
  # there was missed messages in the sequence numbering.
  def print_next_message(self):
    with http_mutex:
      if len(self.http_message_queue):
        self.expected_http_seq_num = self.http_message_queue[0][0]
        self.print_messages_due()

  # Completely flushes all out-of-order messages in the queue.
  def print_all_messages(self):
    with http_mutex:
      while len(self.http_message_queue):
        self.print_next_message()

  # Prints any messages that are now due after we logged some other previous
  # messages.
  def print_messages_due(self):
    with http_mutex:
      while len(self.http_message_queue):
        msg = self.http_message_queue[0]
        if msg[0] == self.expected_http_seq_num:
          msg[2](msg[1])
          self.expected_http_seq_num += 1
          self.http_message_queue.pop(0)
        else:
          return

  def serve_forever(self, timeout=0.5):
    global last_message_time, page_exit_code, emrun_not_enabled_nag_printed
    self.is_running = True
    self.timeout = timeout
    logv("Entering web server loop.")
    while self.is_running:
      now = tick()
      # Did user close browser?
      if emrun_options.run_browser and not is_browser_process_alive():
        logv("Shutting down because browser is no longer alive")
        delete_emrun_safe_firefox_profile()
        if not emrun_options.serve_after_close:
          logv("Browser process has shut down, quitting web server.")
          self.is_running = False

      # Serve HTTP
      self.handle_request()
      # Process message log queue
      self.print_timed_out_messages()

      # If web page was silent for too long without printing anything, kill process.
      time_since_message = now - last_message_time
      if emrun_options.silence_timeout != 0 and time_since_message > emrun_options.silence_timeout:
        self.shutdown()
        logi('No activity in ' + str(emrun_options.silence_timeout) + ' seconds. Quitting web server with return code ' + str(emrun_options.timeout_returncode) + '. (--silence_timeout option)')
        page_exit_code = emrun_options.timeout_returncode
        emrun_options.kill_exit = True

      # If the page has been running too long as a whole, kill process.
      time_since_start = now - page_start_time
      if emrun_options.timeout != 0 and time_since_start > emrun_options.timeout:
        self.shutdown()
        logi('Page has not finished in ' + str(emrun_options.timeout) + ' seconds. Quitting web server with return code ' + str(emrun_options.timeout_returncode) + '. (--timeout option)')
        emrun_options.kill_exit = True
        page_exit_code = emrun_options.timeout_returncode

      # If we detect that the page is not running with emrun enabled, print a warning message.
      if not emrun_not_enabled_nag_printed and page_last_served_time is not None:
        time_since_page_serve = now - page_last_served_time
        if not have_received_messages and time_since_page_serve > 10:
          logv('The html page you are running is not emrun-capable. Stdout, stderr and exit(returncode) capture will not work. Recompile the application with the --emrun linker flag to enable this, or pass --no_emrun_detect to emrun to hide this check.')
          emrun_not_enabled_nag_printed = True

    # Clean up at quit, print any leftover messages in queue.
    self.print_all_messages()
    logv("Web server loop done.")

  def handle_error(self, request, client_address):
    err = sys.exc_info()[1].args[0]
    # Filter out the useless '[Errno 10054] An existing connection was forcibly
    # closed by the remote host' errors that occur when we forcibly kill the
    # client.
    if err != 10054:
      socketserver.BaseServer.handle_error(self, request, client_address)

  def shutdown(self):
    self.is_running = False
    self.print_all_messages()
    return 1


# Processes HTTP request back to the browser.
class HTTPHandler(SimpleHTTPRequestHandler):
  def send_head(self):
    self.protocol_version = 'HTTP/1.1'
    global page_last_served_time
    path = self.translate_path(self.path)
    f = None

    # A browser has navigated to this page - check which PID got spawned for
    # the browser
    global navigation_has_occurred
    if not navigation_has_occurred and current_browser_processes is None:
      detect_browser_processes()

    navigation_has_occurred = True

    if os.path.isdir(path):
      if not self.path.endswith('/'):
        self.send_response(301)
        self.send_header("Location", self.path + "/")
        self.end_headers()
        return None
      for index in "index.html", "index.htm":
        index = os.path.join(path, index)
        if os.path.isfile(index):
          path = index
          break
      else:
        # Manually implement directory listing support.
        return self.list_directory(path)

    try:
      f = open(path, 'rb')
    except IOError:
      self.send_error(404, "File not found: " + path)
      return None

    self.send_response(200)
    guess_file_type = path
    # All files of type x.gz are served as gzip-compressed, which means the
    # browser will transparently decode the file before passing the
    # uncompressed bytes to the JS page.
    # Note: In a slightly silly manner, detect files ending with "gz" and not
    # ".gz", since both Unity and UE4 generate multiple files with .jsgz,
    # .datagz, .memgz, .symbolsgz suffixes and so on, so everything goes.
    # Note 2: If the JS application would like to receive the actual bits of a
    # gzipped file, instead of having the browser decompress it immediately,
    # then it can't use the suffix .gz when using emrun.
    # To work around, one can use the suffix .gzip instead.
    if 'Accept-Encoding' in self.headers and 'gzip' in self.headers['Accept-Encoding'] and path.lower().endswith('gz'):
      self.send_header('Content-Encoding', 'gzip')
      logv('Serving ' + path + ' as gzip-compressed.')
      guess_file_type = guess_file_type[:-2]
      if guess_file_type.endswith('.'):
        guess_file_type = guess_file_type[:-1]

    ctype = self.guess_type(guess_file_type)
    if guess_file_type.lower().endswith('.wasm'):
      ctype = 'application/wasm'
    if guess_file_type.lower().endswith('.js'):
      ctype = 'application/javascript'
    self.send_header('Content-type', ctype)
    fs = os.fstat(f.fileno())
    self.send_header("Content-Length", str(fs[6]))
    self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
    self.send_header('Cache-Control', 'no-cache, must-revalidate')
    self.send_header('Connection', 'close')
    self.send_header('Expires', '-1')
    self.send_header('Access-Control-Allow-Origin', '*')
    self.send_header('Cross-Origin-Opener-Policy', 'same-origin')
    self.send_header('Cross-Origin-Embedder-Policy', 'require-corp')
    self.send_header('Cross-Origin-Resource-Policy', 'cross-origin')
    self.end_headers()
    page_last_served_time = tick()
    return f

  def log_request(self, code):
    # Filter out 200 OK messages to remove noise.
    if code != 200:
      SimpleHTTPRequestHandler.log_request(self, code)

  def log_message(self, format, *args):
    msg = '%s - - [%s] %s\n' % (self.address_string(), self.log_date_time_string(), format % args)
    # Filter out 404 messages on favicon.ico not being found to remove noise.
    if 'favicon.ico' not in msg:
      sys.stderr.write(msg)

  def do_POST(self):
    self.protocol_version = 'HTTP/1.1'
    global page_exit_code, have_received_messages

    (_, _, path, query, _) = urlsplit(self.path)
    logv('POST: "' + self.path + '" (path: "' + path + '", query: "' + query + '")')
    if query.startswith('file='):
      # Binary file dump/upload handling. Requests to
      # "stdio.html?file=filename" will write binary data to the given file.
      data = self.rfile.read(int(self.headers['Content-Length']))
      filename = unquote_u(query[len('file='):])
      filename = os.path.join(emrun_options.dump_out_directory, os.path.normpath(filename))
      try:
        os.makedirs(os.path.dirname(filename))
      except OSError:
        pass
      with open(filename, 'wb') as fh:
        fh.write(data)
      logi('Wrote ' + str(len(data)) + ' bytes to file "' + filename + '".')
      have_received_messages = True
    elif path == '/system_info':
      system_info = json.loads(get_system_info(format_json=True))
      try:
        browser_info = json.loads(get_browser_info(browser_exe, format_json=True))
      except ValueError:
        browser_info = ''
      data = {'system': system_info, 'browser': browser_info}
      self.send_response(200)
      self.send_header('Content-type', 'application/json')
      self.send_header('Cache-Control', 'no-cache, must-revalidate')
      self.send_header('Connection', 'close')
      self.send_header('Expires', '-1')
      self.end_headers()
      self.wfile.write(json.dumps(data))
      return
    else:
      data = self.rfile.read(int(self.headers['Content-Length']))
      if str is not bytes and isinstance(data, bytes):
        data = data.decode('utf-8')
      data = data.replace("+", " ")
      data = unquote_u(data)

      if data == '^pageload^': # Browser is just notifying that it has successfully launched the page.
        have_received_messages = True
      elif data.startswith('^exit^'):
        if not emrun_options.serve_after_exit:
          page_exit_code = int(data[6:])
          logv('Web page has quit with a call to exit() with return code ' + str(page_exit_code) + '. Shutting down web server. Pass --serve_after_exit to keep serving even after the page terminates with exit().')
          self.server.shutdown()
          return
      else:
        # The user page sent a message with POST. Parse the message and log it to stdout/stderr.
        is_stdout = False
        is_stderr = False
        seq_num = -1
        # The html shell is expected to send messages of form ^out^(number)^(message) or ^err^(number)^(message).
        if data.startswith('^err^'):
          is_stderr = True
        elif data.startswith('^out^'):
          is_stdout = True
        if is_stderr or is_stdout:
          try:
            i = data.index('^', 5)
            seq_num = int(data[5:i])
            data = data[i + 1:]
          except ValueError:
            pass

        log = browser_loge if is_stderr else browser_logi
        self.server.handle_incoming_message(seq_num, log, data)

    self.send_response(200)
    self.send_header('Content-type', 'text/plain')
    self.send_header('Cache-Control', 'no-cache, must-revalidate')
    self.send_header('Connection', 'close')
    self.send_header('Expires', '-1')
    self.end_headers()
    self.wfile.write(b'OK')


# Returns stdout by running command with universal_newlines=True
def check_output(cmd, universal_newlines=True, *args, **kwargs):
  if hasattr(subprocess, "run"):
    return subprocess.run(cmd, universal_newlines=universal_newlines, stdout=subprocess.PIPE, check=True, *args, **kwargs).stdout
  else:
    # check_output is considered as an old API so prefer subprocess.run if possible
    return subprocess.check_output(cmd, universal_newlines=universal_newlines, *args, **kwargs)


# From http://stackoverflow.com/questions/4842448/getting-processor-information-in-python
# Returns a string with something like "AMD64, Intel(R) Core(TM) i5-2557M CPU @
# 1.70GHz, Intel64 Family 6 Model 42 Stepping 7, GenuineIntel"
def get_cpu_info():
  physical_cores = 1
  logical_cores = 1
  frequency = 0
  try:
    if WINDOWS:
      from win32com.client import GetObject
      root_winmgmts = GetObject('winmgmts:root\\cimv2')
      cpus = root_winmgmts.ExecQuery('Select * from Win32_Processor')
      cpu_name = cpus[0].Name + ', ' + platform.processor()
      physical_cores = int(check_output(['wmic', 'cpu', 'get', 'NumberOfCores']).split('\n')[1].strip())
      logical_cores = int(check_output(['wmic', 'cpu', 'get', 'NumberOfLogicalProcessors']).split('\n')[1].strip())
      frequency = int(check_output(['wmic', 'cpu', 'get', 'MaxClockSpeed']).split('\n')[1].strip())
    elif MACOS:
      cpu_name = check_output(['sysctl', '-n', 'machdep.cpu.brand_string']).strip()
      physical_cores = int(check_output(['sysctl', '-n', 'machdep.cpu.core_count']).strip())
      logical_cores = int(check_output(['sysctl', '-n', 'machdep.cpu.thread_count']).strip())
      frequency = int(check_output(['sysctl', '-n', 'hw.cpufrequency']).strip()) // 1000000
    elif LINUX:
      all_info = check_output(['cat', '/proc/cpuinfo']).strip()
      for line in all_info.split("\n"):
        if 'model name' in line:
          cpu_name = re.sub('.*model name.*:', '', line, 1).strip()
      lscpu = check_output(['lscpu'])
      frequency = int(float(re.search('CPU MHz: (.*)', lscpu).group(1).strip()) + 0.5)
      sockets = int(re.search(r'Socket\(s\): (.*)', lscpu).group(1).strip())
      physical_cores = sockets * int(re.search(r'Core\(s\) per socket: (.*)', lscpu).group(1).strip())
      logical_cores = physical_cores * int(re.search(r'Thread\(s\) per core: (.*)', lscpu).group(1).strip())
  except Exception as e:
    import traceback
    loge(traceback.format_exc())
    return {'model': 'Unknown ("' + str(e) + '")',
            'physicalCores': 1,
            'logicalCores': 1,
            'frequency': 0
            }

  return {'model': platform.machine() + ', ' + cpu_name,
          'physicalCores': physical_cores,
          'logicalCores': logical_cores,
          'frequency': frequency
          }


def get_android_cpu_infoline():
  lines = check_output([ADB, 'shell', 'cat', '/proc/cpuinfo']).split('\n')
  processor = ''
  hardware = ''
  for line in lines:
    if line.startswith('Processor'):
      processor = line[line.find(':') + 1:].strip()
    elif line.startswith('Hardware'):
      hardware = line[line.find(':') + 1:].strip()

  freq = int(check_output([ADB, 'shell', 'cat', '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq']).strip()) // 1000
  return 'CPU: ' + processor + ', ' + hardware + ' @ ' + str(freq) + ' MHz'


def win_get_gpu_info():
  gpus = []

  def find_gpu_model(model):
    for gpu in gpus:
      if gpu['model'] == model:
        return gpu
    return None

  for i in range(0, 16):
    try:
      hHardwareReg = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'HARDWARE')
      hDeviceMapReg = winreg.OpenKey(hHardwareReg, 'DEVICEMAP')
      hVideoReg = winreg.OpenKey(hDeviceMapReg, 'VIDEO')
      VideoCardString = winreg.QueryValueEx(hVideoReg, '\\Device\\Video' + str(i))[0]
      # Get Rid of Registry/Machine from the string
      VideoCardStringSplit = VideoCardString.split('\\')
      ClearnVideoCardString = "\\".join(VideoCardStringSplit[3:])
      # Go up one level for detailed
      # VideoCardStringRoot = "\\".join(VideoCardStringSplit[3:len(VideoCardStringSplit)-1])

      # Get the graphics card information
      hVideoCardReg = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, ClearnVideoCardString)
      try:
        VideoCardDescription = winreg.QueryValueEx(hVideoCardReg, 'Device Description')[0]
      except WindowsError:
        VideoCardDescription = winreg.QueryValueEx(hVideoCardReg, 'DriverDesc')[0]

      try:
        driverVersion = winreg.QueryValueEx(hVideoCardReg, 'DriverVersion')[0]
        VideoCardDescription += ', driver version ' + driverVersion
      except WindowsError:
        pass

      try:
        driverDate = winreg.QueryValueEx(hVideoCardReg, 'DriverDate')[0]
        VideoCardDescription += ' (' + driverDate + ')'
      except WindowsError:
        pass

      VideoCardMemorySize = winreg.QueryValueEx(hVideoCardReg, 'HardwareInformation.MemorySize')[0]
      try:
        vram = struct.unpack('l', bytes(VideoCardMemorySize))[0]
      except struct.error:
        vram = int(VideoCardMemorySize)
      if not find_gpu_model(VideoCardDescription):
        gpus += [{'model': VideoCardDescription, 'ram': vram}]
    except WindowsError:
      pass
  return gpus


def linux_get_gpu_info():
  glinfo = ''
  try:
    glxinfo = check_output('glxinfo')
    for line in glxinfo.split("\n"):
      if "OpenGL vendor string:" in line:
        gl_vendor = line[len("OpenGL vendor string:"):].strip()
      if "OpenGL version string:" in line:
        gl_version = line[len("OpenGL version string:"):].strip()
      if "OpenGL renderer string:" in line:
        gl_renderer = line[len("OpenGL renderer string:"):].strip()
    glinfo = gl_vendor + ' ' + gl_renderer + ', GL version ' + gl_version
  except Exception as e:
    logv(e)

  adapterinfo = ''
  try:
    vgainfo = check_output(['lshw', '-C', 'display'], stderr=subprocess.PIPE)
    vendor = re.search("vendor: (.*)", vgainfo).group(1).strip()
    product = re.search("product: (.*)", vgainfo).group(1).strip()
    description = re.search("description: (.*)", vgainfo).group(1).strip()
    clock = re.search("clock: (.*)", vgainfo).group(1).strip()
    adapterinfo = vendor + ' ' + product + ', ' + description + ' (' + clock + ')'
  except Exception as e:
    logv(e)

  ram = 0
  try:
    vgainfo = check_output('lspci -v -s $(lspci | grep VGA | cut -d " " -f 1)', shell=True, stderr=subprocess.PIPE)
    ram = int(re.search(r"\[size=([0-9]*)M\]", vgainfo).group(1)) * 1024 * 1024
  except Exception as e:
    logv(e)

  model = (adapterinfo + ' ' + glinfo).strip()
  if not model:
    model = 'Unknown'
  return [{'model': model, 'ram': ram}]


def macos_get_gpu_info():
  gpus = []
  try:
    info = check_output(['system_profiler', 'SPDisplaysDataType'])
    info = info.split("Chipset Model:")[1:]
    for gpu in info:
      model_name = gpu.split('\n')[0].strip()
      bus = re.search("Bus: (.*)", gpu).group(1).strip()
      memory = int(re.search("VRAM (.*?): (.*) MB", gpu).group(2).strip())
      gpus += [{'model': model_name + ' (' + bus + ')', 'ram': memory * 1024 * 1024}]
    return gpus
  except Exception:
    pass


def get_gpu_info():
  if WINDOWS:
    return win_get_gpu_info()
  elif LINUX:
    return linux_get_gpu_info()
  elif MACOS:
    return macos_get_gpu_info()
  else:
    return []


def get_executable_version(filename):
  try:
    if WINDOWS:
      import win32api
      info = win32api.GetFileVersionInfo(filename, "\\")
      ms = info['FileVersionMS']
      ls = info['FileVersionLS']
      version = win32api.HIWORD(ms), win32api.LOWORD(ms), win32api.HIWORD(ls), win32api.LOWORD(ls)
      return '.'.join(map(str, version))
    elif MACOS:
      plistfile = filename[0:filename.find('MacOS')] + 'Info.plist'
      info = plistlib.readPlist(plistfile)
      # Data in Info.plists is a bit odd, this check combo gives best information on each browser.
      if 'firefox' in filename.lower():
        return info['CFBundleShortVersionString']
      if 'opera' in filename.lower():
        return info['CFBundleVersion']
      else:
        return info['CFBundleShortVersionString']
    elif LINUX:
      if 'firefox' in filename.lower():
        version = check_output([filename, '-v'])
        version = version.replace('Mozilla Firefox ', '')
        return version.strip()
      else:
        return ""
  except Exception as e:
    logv(e)
    return ""


def get_browser_build_date(filename):
  try:
    if MACOS:
      plistfile = filename[0:filename.find('MacOS')] + 'Info.plist'
      info = plistlib.readPlist(plistfile)
      # Data in Info.plists is a bit odd, this check combo gives best information on each browser.
      if 'firefox' in filename.lower():
        return '20' + '-'.join(map((lambda x: x.zfill(2)), info['CFBundleVersion'][2:].split('.')))
  except Exception as e:
    logv(e)

  # No exact information about the build date, so take the last modified date of the file.
  # This is not right, but assuming that one installed the browser shortly after the update was
  # available, it's shooting close.
  try:
    return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(os.path.getmtime(filename)))
  except Exception as e:
    logv(e)
    return '(unknown)'


def get_browser_info(filename, format_json):
  if format_json:
    return json.dumps({
      'name': browser_display_name(filename),
      'version': get_executable_version(filename),
      'buildDate': get_browser_build_date(filename)
    }, indent=2)
  else:
    return 'Browser: ' + browser_display_name(filename) + ' ' + get_executable_version(filename) + ', build ' + get_browser_build_date(filename)


# http://stackoverflow.com/questions/580924/python-windows-file-version-attribute
def win_get_file_properties(fname):
  propNames = ('Comments', 'InternalName', 'ProductName',
               'CompanyName', 'LegalCopyright', 'ProductVersion',
               'FileDescription', 'LegalTrademarks', 'PrivateBuild',
               'FileVersion', 'OriginalFilename', 'SpecialBuild')

  props = {'FixedFileInfo': None, 'StringFileInfo': None, 'FileVersion': None}

  import win32api
  # backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc
  fixedInfo = win32api.GetFileVersionInfo(fname, '\\')
  props['FixedFileInfo'] = fixedInfo
  props['FileVersion'] = "%d.%d.%d.%d" % (fixedInfo['FileVersionMS'] / 65536,
                                          fixedInfo['FileVersionMS'] % 65536,
                                          fixedInfo['FileVersionLS'] / 65536,
                                          fixedInfo['FileVersionLS'] % 65536)

  # \VarFileInfo\Translation returns list of available (language, codepage)
  # pairs that can be used to retreive string info. We are using only the first pair.
  lang, codepage = win32api.GetFileVersionInfo(fname, '\\VarFileInfo\\Translation')[0]

  # any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle
  # two are language/codepage pair returned from above

  strInfo = {}
  for propName in propNames:
    strInfoPath = u'\\StringFileInfo\\%04X%04X\\%s' % (lang, codepage, propName)
    ## print str_info
    strInfo[propName] = win32api.GetFileVersionInfo(fname, strInfoPath)

  props['StringFileInfo'] = strInfo

  return props


def get_computer_model():
  try:
    if MACOS:
      try:
        with open(os.path.join(os.getenv("HOME"), '.emrun.hwmodel.cached'), 'r') as f:
          model = f.read()
          return model
      except IOError:
        pass

      try:
        # http://apple.stackexchange.com/questions/98080/can-a-macs-model-year-be-determined-via-terminal-command
        serial = check_output(['system_profiler', 'SPHardwareDataType'])
        serial = re.search("Serial Number (.*): (.*)", serial)
        serial = serial.group(2).strip()[-4:]
        cmd = ['curl', '-s', 'http://support-sp.apple.com/sp/product?cc=' + serial]
        logv(str(cmd))
        model = check_output(cmd)
        model = re.search('<configCode>(.*)</configCode>', model)
        model = model.group(1).strip()
        with open(os.path.join(os.getenv("HOME"), '.emrun.hwmodel.cached'), 'w') as fh:
          fh.write(model) # Cache the hardware model to disk
        return model
      except Exception:
        hwmodel = check_output(['sysctl', 'hw.model'])
        hwmodel = re.search('hw.model: (.*)', hwmodel).group(1).strip()
        return hwmodel
    elif WINDOWS:
      manufacturer = check_output(['wmic', 'baseboard', 'get', 'manufacturer']).split('\n')[1].strip()
      version = check_output(['wmic', 'baseboard', 'get', 'version']).split('\n')[1].strip()
      product = check_output(['wmic', 'baseboard', 'get', 'product']).split('\n')[1].strip()
      if 'Apple' in manufacturer:
        return manufacturer + ' ' + version + ', ' + product
      else:
        return manufacturer + ' ' + product + ', ' + version
    elif LINUX:
      board_vendor = check_output(['cat', '/sys/devices/virtual/dmi/id/board_vendor']).strip()
      board_name = check_output(['cat', '/sys/devices/virtual/dmi/id/board_name']).strip()
      board_version = check_output(['cat', '/sys/devices/virtual/dmi/id/board_version']).strip()

      bios_vendor = check_output(['cat', '/sys/devices/virtual/dmi/id/bios_vendor']).strip()
      bios_version = check_output(['cat', '/sys/devices/virtual/dmi/id/bios_version']).strip()
      bios_date = check_output(['cat', '/sys/devices/virtual/dmi/id/bios_date']).strip()
      return board_vendor + ' ' + board_name + ' ' + board_version + ', ' + bios_vendor + ' ' + bios_version + ' (' + bios_date + ')'
  except Exception as e:
    logv(str(e))
  return 'Generic'


def get_os_version():
  bitness = ' (64bit)' if platform.machine() in ['AMD64', 'x86_64'] else ' (32bit)'
  try:
    if WINDOWS:
      versionHandle = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion")
      productName = winreg.QueryValueEx(versionHandle, "ProductName")

      version = ''
      try:
        version = ' ' + check_output(['wmic', 'os', 'get', 'version']).split('\n')[1].strip()
      except Exception:
        pass
      return productName[0] + version + bitness
    elif MACOS:
      return 'macOS ' + platform.mac_ver()[0] + bitness
    elif LINUX:
      kernel_version = check_output(['uname', '-r']).strip()
      return ' '.join(platform.linux_distribution()) + ', linux kernel ' + kernel_version + ' ' + platform.architecture()[0] + bitness
  except Exception:
    return 'Unknown OS'


def get_system_memory():
  try:
    if LINUX or emrun_options.android:
      if emrun_options.android:
        lines = check_output([ADB, 'shell', 'cat', '/proc/meminfo']).split('\n')
      else:
        mem = open('/proc/meminfo', 'r')
        lines = mem.readlines()
        mem.close()
      for i in lines:
        sline = i.split()
        if str(sline[0]) == 'MemTotal:':
          return int(sline[1]) * 1024
    elif WINDOWS:
      import win32api
      return win32api.GlobalMemoryStatusEx()['TotalPhys']
    elif MACOS:
      return int(check_output(['sysctl', '-n', 'hw.memsize']).strip())
  except Exception:
    return -1


# Finds the given executable 'program' in PATH. Operates like the Unix tool 'which'.
def which(program):
  def is_exe(fpath):
    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

  fpath, fname = os.path.split(program)
  if fpath:
    if is_exe(program):
      return program
  else:
    for path in os.environ["PATH"].split(os.pathsep):
      path = path.strip('"')
      exe_file = os.path.join(path, program)
      if is_exe(exe_file):
        return exe_file

      if WINDOWS and '.' not in fname:
        if is_exe(exe_file + '.exe'):
          return exe_file + '.exe'
        if is_exe(exe_file + '.cmd'):
          return exe_file + '.cmd'
        if is_exe(exe_file + '.bat'):
          return exe_file + '.bat'

  return None


def win_get_default_browser():
  # Look in the registry for the default system browser on Windows without relying on
  # 'start %1' since that method has an issue, see comment below.
  try:
    with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Classes\http\shell\open\command") as key:
      cmd = winreg.QueryValue(key, None)
      if cmd:
        parts = shlex.split(cmd)
        if len(parts):
          return [parts[0]]
  except WindowsError:
    logv("Unable to find default browser key in Windows registry. Trying fallback.")

  # Fall back to 'start "" %1', which we have to treat as if user passed --serve_forever, since
  # for some reason, we are not able to detect when the browser closes when this is passed.
  #
  # If the first argument to 'start' is quoted, then 'start' will create a new cmd.exe window with
  # that quoted string as the title. If the URL contained spaces, it would be quoted by subprocess,
  # and if we did 'start %1', it would create a new cmd.exe window with the URL as title instead of
  # actually launching the browser. Therefore, we must pass a dummy quoted first argument for start
  # to interpret as the title. For this purpose, we use the empty string, which will be quoted
  # as "". See #9253 for details.
  return ['cmd', '/C', 'start', '']


def find_browser(name):
  if WINDOWS and name == 'start':
    return win_get_default_browser()
  if MACOS and name == 'open':
    return [name]

  if os.path.isfile(os.path.abspath(name)):
    return [name]
  if os.path.isfile(os.path.abspath(name) + '.exe'):
    return [os.path.abspath(name) + '.exe']
  if os.path.isfile(os.path.abspath(name) + '.cmd'):
    return [os.path.abspath(name) + '.cmd']
  if os.path.isfile(os.path.abspath(name) + '.bat'):
    return [os.path.abspath(name) + '.bat']

  path_lookup = which(name)
  if path_lookup is not None:
    return [path_lookup]

  browser_locations = []
  if MACOS:
    # Note: by default Firefox beta installs as 'Firefox.app', you must manually rename it to
    # FirefoxBeta.app after installation.
    browser_locations = [('firefox', '/Applications/Firefox.app/Contents/MacOS/firefox'),
                         ('firefox_beta', '/Applications/FirefoxBeta.app/Contents/MacOS/firefox'),
                         ('firefox_aurora', '/Applications/FirefoxAurora.app/Contents/MacOS/firefox'),
                         ('firefox_nightly', '/Applications/FirefoxNightly.app/Contents/MacOS/firefox'),
                         ('safari', '/Applications/Safari.app/Contents/MacOS/Safari'),
                         ('opera', '/Applications/Opera.app/Contents/MacOS/Opera'),
                         ('chrome', '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
                         ('chrome_canary', '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary')]
  elif WINDOWS:
    pf_locations = ['ProgramFiles(x86)', 'ProgramFiles', 'ProgramW6432']

    for pf_env in pf_locations:
      if pf_env not in os.environ:
        continue
      program_files = os.environ[pf_env] if WINDOWS else ''

      browser_locations += [('chrome', os.path.join(program_files, 'Google/Chrome/Application/chrome.exe')),
                            ('chrome_canary', os.path.expanduser("~/AppData/Local/Google/Chrome SxS/Application/chrome.exe")),
                            ('firefox_nightly', os.path.join(program_files, 'Nightly/firefox.exe')),
                            ('firefox_aurora', os.path.join(program_files, 'Aurora/firefox.exe')),
                            ('firefox_beta', os.path.join(program_files, 'Beta/firefox.exe')),
                            ('firefox_beta', os.path.join(program_files, 'FirefoxBeta/firefox.exe')),
                            ('firefox_beta', os.path.join(program_files, 'Firefox Beta/firefox.exe')),
                            ('firefox', os.path.join(program_files, 'Mozilla Firefox/firefox.exe')),
                            ('iexplore', os.path.join(program_files, 'Internet Explorer/iexplore.exe')),
                            ('opera', os.path.join(program_files, 'Opera/launcher.exe'))]

  elif LINUX:
    browser_locations = [('firefox', os.path.expanduser('~/firefox/firefox')),
                         ('firefox_beta', os.path.expanduser('~/firefox_beta/firefox')),
                         ('firefox_aurora', os.path.expanduser('~/firefox_aurora/firefox')),
                         ('firefox_nightly', os.path.expanduser('~/firefox_nightly/firefox')),
                         ('chrome', which('google-chrome-stable')),
                         ('chrome', which('google-chrome'))]

  for alias, browser_exe in browser_locations:
    if name == alias:
      if browser_exe is not None and os.path.isfile(browser_exe):
        return [browser_exe]

  return None # Could not find the browser


def get_android_model():
  manufacturer = check_output([ADB, 'shell', 'getprop', 'ro.product.manufacturer']).strip()
  brand = check_output([ADB, 'shell', 'getprop', 'ro.product.brand']).strip()
  model = check_output([ADB, 'shell', 'getprop', 'ro.product.model']).strip()
  board = check_output([ADB, 'shell', 'getprop', 'ro.product.board']).strip()
  device = check_output([ADB, 'shell', 'getprop', 'ro.product.device']).strip()
  name = check_output([ADB, 'shell', 'getprop', 'ro.product.name']).strip()
  return manufacturer + ' ' + brand + ' ' + model + ' ' + board + ' ' + device + ' ' + name


def get_android_os_version():
  ver = check_output([ADB, 'shell', 'getprop', 'ro.build.version.release']).strip()
  apiLevel = check_output([ADB, 'shell', 'getprop', 'ro.build.version.sdk']).strip()
  if not apiLevel:
    apiLevel = check_output([ADB, 'shell', 'getprop', 'ro.build.version.sdk_int']).strip()

  os = ''
  if ver:
    os += 'Android ' + ver + ' '
  if apiLevel:
    os += 'SDK API Level ' + apiLevel + ' '
  os += check_output([ADB, 'shell', 'getprop', 'ro.build.description']).strip()
  return os


def list_android_browsers():
  apps = check_output([ADB, 'shell', 'pm', 'list', 'packages', '-f']).replace('\r\n', '\n')
  browsers = []
  for line in apps.split('\n'):
    line = line.strip()
    if line.endswith('=org.mozilla.firefox'):
      browsers += ['firefox']
    if line.endswith('=org.mozilla.firefox_beta'):
      browsers += ['firefox_beta']
    if line.endswith('=org.mozilla.fennec_aurora'):
      browsers += ['firefox_aurora']
    if line.endswith('=org.mozilla.fennec'):
      browsers += ['firefox_nightly']
    if line.endswith('=com.android.chrome'):
      browsers += ['chrome']
    if line.endswith('=com.chrome.beta'):
      browsers += ['chrome_beta']
    if line.endswith('=com.chrome.dev'):
      browsers += ['chrome_dev']
    if line.endswith('=com.chrome.canary'):
      browsers += ['chrome_canary']
    if line.endswith('=com.opera.browser'):
      browsers += ['opera']
    if line.endswith('=com.opera.mini.android'):
      browsers += ['opera_mini']
    if line.endswith('=mobi.mgeek.TunnyBrowser'):
      browsers += ['dolphin']

  browsers.sort()
  logi('emrun has automatically found the following browsers on the connected Android device:')
  for browser in browsers:
    logi('  - ' + browser)


def list_pc_browsers():
  browsers = ['firefox', 'firefox_beta', 'firefox_aurora', 'firefox_nightly', 'chrome', 'chrome_canary', 'iexplore', 'safari', 'opera']
  logi('emrun has automatically found the following browsers in the default install locations on the system:')
  logi('')
  for browser in browsers:
    browser_exe = find_browser(browser)
    if type(browser_exe) == list:
      browser_exe = browser_exe[0]
    if browser_exe:
      logi('  - ' + browser + ': ' + browser_display_name(browser_exe) + ' ' + get_executable_version(browser_exe))
  logi('')
  logi('You can pass the --browser <id> option to launch with the given browser above.')
  logi('Even if your browser was not detected, you can use --browser /path/to/browser/executable to launch with that browser.')


def browser_display_name(browser):
  b = browser.lower()
  if 'iexplore' in b:
    return 'Microsoft Internet Explorer'
  if 'chrome' in b:
    return 'Google Chrome'
  if 'firefox' in b:
    # Try to identify firefox flavor explicitly, to help show issues where emrun would launch the wrong browser.
    try:
      product_name = win_get_file_properties(browser)['StringFileInfo']['ProductName'] if WINDOWS else 'firefox'
      if product_name.lower() != 'firefox':
        return 'Mozilla Firefox ' + product_name
    except Exception:
      pass
    return 'Mozilla Firefox'
  if 'opera' in b:
    return 'Opera'
  if 'safari' in b:
    return 'Apple Safari'
  return browser


def subprocess_env():
  e = os.environ.copy()
  # https://bugzilla.mozilla.org/show_bug.cgi?id=745154
  e['MOZ_DISABLE_AUTO_SAFE_MODE'] = '1'
  e['MOZ_DISABLE_SAFE_MODE_KEY'] = '1' # https://bugzilla.mozilla.org/show_bug.cgi?id=653410#c9
  e['JIT_OPTION_asmJSAtomicsEnable'] = 'true' # https://bugzilla.mozilla.org/show_bug.cgi?id=1299359#c0
  return e


# Removes a directory tree even if it was readonly, and doesn't throw exception on failure.
def remove_tree(d):
  os.chmod(d, stat.S_IWRITE)
  try:
    def remove_readonly_and_try_again(func, path, _exc_info):
      if not (os.stat(path).st_mode & stat.S_IWRITE):
        os.chmod(path, stat.S_IWRITE)
        func(path)
      else:
        raise
    shutil.rmtree(d, onerror=remove_readonly_and_try_again)
  except Exception:
    pass


def get_system_info(format_json):
  if emrun_options.android:
    if format_json:
      return json.dumps({'model': get_android_model(),
                         'os': get_android_os_version(),
                         'ram': get_system_memory(),
                         'cpu': get_android_cpu_infoline()
                         }, indent=2)
    else:
      info = 'Model: ' + get_android_model() + '\n'
      info += 'OS: ' + get_android_os_version() + ' with ' + str(get_system_memory() // 1024 // 1024) + ' MB of System RAM\n'
      info += 'CPU: ' + get_android_cpu_infoline() + '\n'
      return info.strip()
  else:
    try:
      with open(os.path.expanduser('~/.emrun.generated.guid')) as fh:
        unique_system_id = fh.read().strip()
    except Exception:
      import uuid
      unique_system_id = str(uuid.uuid4())
      try:
        open(os.path.expanduser('~/.emrun.generated.guid'), 'w').write(unique_system_id)
      except Exception as e:
        logv(e)

    if format_json:
      return json.dumps({'name': socket.gethostname(),
                         'model': get_computer_model(),
                         'os': get_os_version(),
                         'ram': get_system_memory(),
                         'cpu': get_cpu_info(),
                         'gpu': get_gpu_info(),
                         'uuid': unique_system_id}, indent=2)
    else:
      cpu = get_cpu_info()
      gpus = get_gpu_info()
      info = 'Computer name: ' + socket.gethostname() + '\n' # http://stackoverflow.com/questions/799767/getting-name-of-windows-computer-running-python-script
      info += 'Model: ' + get_computer_model() + '\n'
      info += 'OS: ' + get_os_version() + ' with ' + str(get_system_memory() // 1024 // 1024) + ' MB of System RAM\n'
      info += 'CPU: ' + cpu['model'] + ', ' + str(cpu['frequency']) + ' MHz, ' + str(cpu['physicalCores']) + ' physical cores, ' + str(cpu['logicalCores']) + ' logical cores\n'
      if len(gpus) == 1:
        info += 'GPU: ' + gpus[0]['model'] + ' with ' + str(gpus[0]['ram'] // 1024 // 1024) + " MB of VRAM\n"
      elif len(gpus) > 1:
        for i in range(0, len(gpus)):
          info += 'GPU' + str(i) + ": " + gpus[i]['model'] + ' with ' + str(gpus[i]['ram'] // 1024 // 1024) + ' MBs of VRAM\n'
      info += 'UUID: ' + unique_system_id
      return info.strip()


# Be resilient to quotes and whitespace
def unwrap(s):
  s = s.strip()
  if (s.startswith('"') and s.endswith('"')) or (s.startswith("'") and s.endswith("'")):
    s = s[1:-1].strip()
  return s


def list_processes_by_name(exe_full_path):
  pids = []
  try:
    import psutil
    for proc in psutil.process_iter():
      try:
        pinfo = proc.as_dict(attrs=['pid', 'name', 'exe'])
        if pinfo['exe'].lower().replace('\\', '/') == exe_full_path.lower().replace('\\', '/'):
          pids.append(pinfo)
      except Exception:
        # Fail gracefully if unable to iterate over a specific process
        pass
  except Exception:
    # Fail gracefully if psutil not available
    logv('import psutil failed, unable to detect browser processes')
    pass

  logv('Searching for processes by full path name "' + exe_full_path + '".. found ' + str(len(pids)) + ' entries')

  return pids


usage_str = """\
emrun [emrun_options] filename.html -- [html_cmdline_options]

   where emrun_options specifies command line options for emrun itself, whereas
   html_cmdline_options specifies startup arguments to the program.

If you are seeing "unrecognized arguments" when trying to pass
arguments to your page, remember to add `--` between arguments
to emrun itself and arguments to your page.
"""


def parse_args():
  parser = argparse.ArgumentParser(usage=usage_str)

  parser.add_argument('--kill_start', action='store_true',
                      help='If true, any previously running instances of '
                           'the target browser are killed before starting.')

  parser.add_argument('--kill_exit', action='store_true',
                      help='If true, the spawned browser process is forcibly '
                           'killed when it calls exit(). Note: Using this '
                           'option may require explicitly passing the option '
                           '--browser=/path/to/browser, to avoid emrun being '
                           'detached from the browser process it spawns.')

  parser.add_argument('--no_server', dest='run_server', action='store_false',
                      default=True,
                      help='If specified, a HTTP web server is not launched '
                           'to host the page to run.')

  parser.add_argument('--no_browser', dest='run_browser', action='store_false',
                      default=True,
                      help='If specified, emrun will not launch a web browser '
                           'to run the page.')

  parser.add_argument('--no_emrun_detect', action='store_true',
                      help='If specified, skips printing the warning message '
                           'if html page is detected to not have been built '
                           'with --emrun linker flag.')

  parser.add_argument('--serve_after_close', action='store_true',
                      help='If true, serves the web page even after the '
                           'application quits by user closing the web page.')

  parser.add_argument('--serve_after_exit', action='store_true',
                      help='If true, serves the web page even after the '
                           'application quits by a call to exit().')

  parser.add_argument('--serve_root',
                      help='If set, specifies the root path that the emrun '
                           'web server serves. If not specified, the directory '
                           'where the target .html page lives in is served.')

  parser.add_argument('--verbose', action='store_true',
                      help='Enable verbose logging from emrun internal operation.')

  parser.add_argument('--hostname', default=default_webserver_hostname,
                      help='Specifies the hostname the server runs in.')

  parser.add_argument('--port', default=default_webserver_port, type=int,
                      help='Specifies the port the server runs in.')

  parser.add_argument('--log_stdout',
                      help='Specifies a log filename where the browser process '
                           'stdout data will be appended to.')

  parser.add_argument('--log_stderr',
                      help='Specifies a log filename where the browser process stderr data will be appended to.')

  parser.add_argument('--silence_timeout', type=int, default=0,
                      help='If no activity is received in this many seconds, '
                           'the browser process is assumed to be hung, and the web '
                           'server is shut down and the target browser killed.  '
                           'Disabled by default.')

  parser.add_argument('--timeout', type=int, default=0,
                      help='If the browser process does not quit or the page '
                           'exit() in this many seconds, the browser is assumed '
                           'to be hung, and the web server is shut down and the '
                           'target browser killed. Disabled by default.')

  parser.add_argument('--timeout_returncode', type=int, default=99999,
                      help='Sets the exit code that emrun reports back to '
                           'caller in the case that a page timeout occurs. '
                           'Default: 99999.')

  parser.add_argument('--list_browsers', action='store_true',
                      help='Prints out all detected browser that emrun is able '
                           'to use with the --browser command and exits.')

  parser.add_argument('--browser',
                      help='Specifies the browser executable to run the web page in.')

  parser.add_argument('--browser_args', default='',
                      help='Specifies the arguments to the browser executable.')

  parser.add_argument('--android', action='store_true',
                      help='Launches the page in a browser of an Android '
                           'device connected to an USB on the local system. (via adb)')

  parser.add_argument('--system_info', action='store_true',
                      help='Prints information about the current system at startup.')

  parser.add_argument('--browser_info', action='store_true',
                      help='Prints information about the target browser to launch at startup.')

  parser.add_argument('--json', action='store_true',
                      help='If specified, --system_info and --browser_info are '
                           'outputted in JSON format.')

  parser.add_argument('--safe_firefox_profile', action='store_true',
                      help='If true, the browser is launched into a new clean '
                           'Firefox profile that is suitable for unattended '
                           'automated runs. (If target browser != Firefox, '
                           'this parameter is ignored)')

  parser.add_argument('--log_html', action='store_true',
                      help='If set, information lines are printed out an HTML-friendly format.')

  parser.add_argument('--private_browsing', action='store_true',
                      help='If specified, opens browser in private/incognito mode.')

  parser.add_argument('--dump_out_directory', default='dump_out', type=str,
                      help='If specified, overrides the directory for dump files using emrun_file_dump method.')

  parser.add_argument('serve', nargs='?', default='')

  parser.add_argument('cmdlineparams', nargs='*')

  return parser.parse_args()


def run():
  global browser_process, browser_exe, processname_killed_atexit, emrun_options, emrun_not_enabled_nag_printed

  options = emrun_options = parse_args()

  if options.android:
    global ADB
    ADB = which('adb')
    if not ADB:
      loge("Could not find the adb tool. Install Android SDK and add the directory of adb to PATH.")
      return 1

  if not options.browser and not options.android:
    if WINDOWS:
      options.browser = 'start'
    elif LINUX:
      options.browser = which('xdg-open')
      if not options.browser:
        options.browser = 'firefox'
    elif MACOS:
      options.browser = 'open'

  if options.list_browsers:
    if options.android:
      list_android_browsers()
    else:
      list_pc_browsers()
    return

  if not options.serve and (options.system_info or options.browser_info):
    # Don't run if only --system_info or --browser_info was passed.
    options.run_server = options.run_browser = False

  if not options.serve and (options.run_server or options.run_browser):
    logi(usage_str)
    logi('')
    logi('Type emrun --help for a detailed list of available options.')
    return

  if options.serve:
    file_to_serve = options.serve
  else:
    file_to_serve = '.'
  file_to_serve_is_url = file_to_serve.startswith('file://') or file_to_serve.startswith('http://') or file_to_serve.startswith('https://')

  if options.serve_root:
    serve_dir = os.path.abspath(options.serve_root)
  else:
    if file_to_serve == '.' or file_to_serve_is_url:
      serve_dir = os.path.abspath('.')
    else:
      if file_to_serve.endswith('/') or file_to_serve.endswith('\\') or os.path.isdir(file_to_serve):
        serve_dir = file_to_serve
      else:
        serve_dir = os.path.dirname(os.path.abspath(file_to_serve))
  if file_to_serve_is_url:
    url = file_to_serve
  else:
    url = os.path.relpath(os.path.abspath(file_to_serve), serve_dir)
    if len(options.cmdlineparams):
      url += '?' + '&'.join(options.cmdlineparams)
    hostname = socket.gethostbyname(socket.gethostname()) if options.android else options.hostname
    url = 'http://' + hostname + ':' + str(options.port) + '/' + url

  os.chdir(serve_dir)
  if options.run_server:
    if options.run_browser:
      logv('Web server root directory: ' + os.path.abspath('.'))
    else:
      logi('Web server root directory: ' + os.path.abspath('.'))

  if options.android:
    if options.run_browser or options.browser_info:
      if not options.browser:
        loge("Running on Android requires that you explicitly specify the browser to run with --browser <id>. Run emrun --android --list_browsers to obtain a list of installed browsers you can use.")
        return 1
      elif options.browser == 'firefox':
        browser_app = 'org.mozilla.firefox/.App'
      elif options.browser == 'firefox_beta':
        browser_app = 'org.mozilla.firefox_beta/.App'
      elif options.browser == 'firefox_aurora' or options.browser == 'fennec_aurora':
        browser_app = 'org.mozilla.fennec_aurora/.App'
      elif options.browser == 'firefox_nightly' or options.browser == 'fennec':
        browser_app = 'org.mozilla.fennec/.App'
      elif options.browser == 'chrome':
        browser_app = 'com.android.chrome/com.google.android.apps.chrome.Main'
      elif options.browser == 'chrome_beta':
        browser_app = 'com.chrome.beta/com.google.android.apps.chrome.Main'
      elif options.browser == 'chrome_dev':
        browser_app = 'com.chrome.dev/com.google.android.apps.chrome.Main'
      elif options.browser == 'chrome_canary':
        browser_app = 'com.chrome.canary/com.google.android.apps.chrome.Main'
      elif options.browser == 'opera':
        browser_app = 'com.opera.browser/com.opera.Opera'
      elif options.browser == 'opera_mini':
        # Launching the URL works, but page seems to never load (Fails with 'Network problem' even when other browsers work)
        browser_app = 'com.opera.mini.android/.Browser'
      elif options.browser == 'dolphin':
        # Current stable Dolphin as of 12/2013 does not have WebGL support.
        browser_app = 'mobi.mgeek.TunnyBrowser/.BrowserActivity'
      else:
        loge("Don't know how to launch browser " + options.browser + ' on Android!')
        return 1
      # To add support for a new Android browser in the list above:
      # 1. Install the browser to Android phone, connect it via adb to PC.
      # 2. Type 'adb shell pm list packages -f' to locate the package name of that application.
      # 3. Type 'adb pull <packagename>.apk' to copy the apk of that application to PC.
      # 4. Type 'aapt d xmltree <packagename>.apk AndroidManifest.xml > manifest.txt' to extract the manifest from the package.
      # 5. Locate the name of the main activity for the browser in manifest.txt and add an entry to above list in form 'appname/mainactivityname'

      url = url.replace('&', '\\&')
      browser = [ADB, 'shell', 'am', 'start', '-a', 'android.intent.action.VIEW', '-n', browser_app, '-d', url]
      processname_killed_atexit = browser_app[:browser_app.find('/')]
  else: # Launching a web page on local system.
    if options.browser:
      options.browser = unwrap(options.browser)

    if options.run_browser or options.browser_info:
      browser = find_browser(str(options.browser))
      if not browser:
        loge('Unable to find browser "' + str(options.browser) + '"! Check the correctness of the passed --browser=xxx parameter!')
        return 1
      browser_exe = browser[0]
      browser_args = shlex.split(unwrap(options.browser_args))

      if MACOS and ('safari' in browser_exe.lower() or browser_exe == 'open'):
        # Safari has a bug that a command line 'Safari http://page.com' does
        # not launch that page, but instead launches 'file:///http://page.com'.
        # To remedy this, must use the open -a command to run Safari, but
        # unfortunately this will end up spawning Safari process detached from
        # emrun.
        browser = ['open', '-a', 'Safari'] + (browser[1:] if len(browser) > 1 else [])
        browser_exe = '/Applications/Safari.app/Contents/MacOS/Safari'
        processname_killed_atexit = 'Safari'
      elif 'chrome' in browser_exe.lower():
        processname_killed_atexit = 'chrome'
        browser_args += ['--enable-nacl', '--enable-pnacl', '--disable-restore-session-state', '--enable-webgl', '--no-default-browser-check', '--no-first-run', '--allow-file-access-from-files']
        if options.private_browsing:
          browser_args += ['--incognito']
    #    if not options.run_server:
    #      browser_args += ['--disable-web-security']
      elif 'firefox' in browser_exe.lower():
        processname_killed_atexit = 'firefox'
      elif 'iexplore' in browser_exe.lower():
        processname_killed_atexit = 'iexplore'
        if options.private_browsing:
          browser_args += ['-private']
      elif 'opera' in browser_exe.lower():
        processname_killed_atexit = 'opera'

      # In Windows cmdline, & character delimits multiple commmands, so must
      # use ^ to escape them.
      if browser_exe == 'cmd':
        url = url.replace('&', '^&')
      url = url.replace('0.0.0.0', 'localhost')
      browser += browser_args + [url]

  if options.kill_start:
    pname = processname_killed_atexit
    kill_browser_process()
    processname_killed_atexit = pname

  # Copy the profile over to Android.
  if options.android and options.safe_firefox_profile:
    profile_dir = create_emrun_safe_firefox_profile()

    def run(cmd):
      logi(str(cmd))
      subprocess.call(cmd)

    run(['adb', 'shell', 'rm', '-rf', '/mnt/sdcard/safe_firefox_profile'])
    run(['adb', 'shell', 'mkdir', '/mnt/sdcard/safe_firefox_profile'])
    run(['adb', 'push', os.path.join(profile_dir, 'prefs.js'), '/mnt/sdcard/safe_firefox_profile/prefs.js'])
    browser += ['--es', 'args', '"--profile /mnt/sdcard/safe_firefox_profile"']

  # Create temporary Firefox profile to run the page with. This is important to
  # run after kill_browser_process()/kill_start op above, since that cleans up
  # the temporary profile if one exists.
  if processname_killed_atexit == 'firefox' and options.safe_firefox_profile and options.run_browser and not options.android:
    profile_dir = create_emrun_safe_firefox_profile()

    browser += ['-no-remote', '--profile', profile_dir.replace('\\', '/')]

  if options.system_info:
    logi('Time of run: ' + time.strftime("%x %X"))
    logi(get_system_info(format_json=options.json))

  if options.browser_info:
    if options.android:
      if options.json:
        logi(json.dumps({'browser': 'Android ' + browser_app}, indent=2))
      else:
        logi('Browser: Android ' + browser_app)
    else:
      logi(get_browser_info(browser_exe, format_json=options.json))

  # Suppress run warning if requested.
  if options.no_emrun_detect:
    emrun_not_enabled_nag_printed = True

  if options.log_stdout:
    global browser_stdout_handle
    browser_stdout_handle = open(options.log_stdout, 'a')
  if options.log_stderr:
    global browser_stderr_handle
    if options.log_stderr == options.log_stdout:
      browser_stderr_handle = browser_stdout_handle
    else:
      browser_stderr_handle = open(options.log_stderr, 'a')

  if options.run_server:
    logv('Starting web server: http://%s:%i/' % (options.hostname, options.port))
    httpd = HTTPWebServer((options.hostname, options.port), HTTPHandler)

  if options.run_browser:
    logv("Starting browser: %s" % ' '.join(browser))
    # if browser[0] == 'cmd':
    #   Workaround an issue where passing 'cmd /C start' is not able to detect
    #   when the user closes the page.
    #   serve_forever = True
    if browser_exe:
      global previous_browser_processes
      logv(browser_exe)
      previous_browser_processes = list_processes_by_name(browser_exe)
      for p in previous_browser_processes:
        logv('Before spawning web browser, found a running ' + os.path.basename(browser_exe) + ' browser process id: ' + str(p['pid']))
    browser_process = subprocess.Popen(browser, env=subprocess_env())
    logv('Launched browser process with pid=' + str(browser_process.pid))
    if options.kill_exit:
      atexit.register(kill_browser_process)
    # For Android automation, we execute adb, so this process does not
    # represent a browser and no point killing it.
    if options.android:
      browser_process = None
  elif options.run_server:
    logi('Now listening at http://%s:%i/' % (options.hostname, options.port))

  if browser_process:
    premature_quit_code = browser_process.poll()
    if premature_quit_code is not None:
      options.serve_after_close = True
      logv('Warning: emrun got immediately detached from the target browser process (the process quit with exit code ' + str(premature_quit_code) + '). Cannot detect when user closes the browser. Behaving as if --serve_after_close was passed in.')
      if not options.browser:
        logv('Try passing the --browser=/path/to/browser option to avoid this from occurring. See https://github.com/emscripten-core/emscripten/issues/3234 for more discussion.')

  if options.run_server:
    try:
      httpd.serve_forever()
    except KeyboardInterrupt:
      pass
    httpd.server_close()

    logv('Closed web server.')

  if options.run_browser:
    if options.kill_exit:
      kill_browser_process()
    else:
      if is_browser_process_alive():
        logv('Not terminating browser process, pass --kill_exit to terminate the browser when it calls exit().')
      # If we have created a temporary Firefox profile, we would really really
      # like to wait until the browser closes, or otherwise we'll just have to
      # litter temp files and keep the temporary profile alive. It is possible
      # here that the browser is cooperatively shutting down, but has not yet
      # had time to do so, so wait for a short while.
      if temp_firefox_profile_dir is not None:
        time.sleep(3)

    if not is_browser_process_alive():
      # Browser is no longer running, make sure to clean up the temp Firefox
      # profile, if we created one.
      delete_emrun_safe_firefox_profile()

  return page_exit_code


def main():
  returncode = run()
  logv('emrun quitting with process exit code ' + str(returncode))
  if temp_firefox_profile_dir is not None:
    logi('Warning: Had to leave behind a temporary Firefox profile directory ' + temp_firefox_profile_dir + ' because --safe_firefox_profile was set and the browser did not quit before emrun did.')
  return returncode


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