#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import codecs
import logging
import os.path
import requests
import signal
import subprocess
import sys
import tempfile


from android_gdb.install_remote_file_reader import install
from devtoolslib import paths


_MOJO_DEBUGGER_PORT = 7777
_DEFAULT_PACKAGE_NAME = 'org.chromium.mojo.shell'


# TODO(etiennej): Refactor with similar methods in subdirectories
class DirectoryNotFoundException(Exception):
  """Directory has not been found."""
  pass


def _get_dir_above(dirname):
  """Returns the directory "above" this file containing |dirname|."""
  path = paths.find_ancestor_with(dirname)
  if not path:
    raise DirectoryNotFoundException(dirname)
  return path


def _send_request(request, payload=None):
  """Sends a request to mojo:debugger."""
  try:
    url = 'http://localhost:%s/%s' % (_MOJO_DEBUGGER_PORT, request)
    if payload:
      return requests.post(url, payload)
    else:
      return requests.get(url)
  except requests.exceptions.ConnectionError:
    print ('Failed to connect to debugger.mojo. Make sure the shell is running '
           'and the app was started with debugger, ie. through '
           '`mojo_run --debugger APP_URL`')

    return None


def _tracing_start(_):
  """Starts tracing."""
  if not _send_request('start_tracing'):
    return 1
  print "Started tracing."
  return 0


def _tracing_stop(args):
  """Stops tracing and writes trace to file."""
  if args.file_name:
    file_name = args.file_name
  else:
    for i in xrange(1000):
      candidate_file_name = 'mojo_trace_%03d.json' % i
      if not os.path.exists(candidate_file_name):
        file_name = candidate_file_name
        break
    else:
      print 'Failed to pick a name for the trace output file.'
      return 1

  response = _send_request('stop_tracing')
  if not response:
    return 1

  # https://github.com/domokit/mojo/issues/253
  if int(response.headers['content-length']) != len(response.content):
    print 'Response is truncated.'
    return 1

  with open(file_name, "wb") as trace_file:
    trace_file.write('{"traceEvents":[')
    trace_file.write(response.content)
    trace_file.write(']}')
  print "Trace saved in %s" % file_name
  return 0


def _add_tracing_command(subparsers):
  """Sets up the command line parser to manage tracing."""
  tracing_parser = subparsers.add_parser('tracing',
      help='tracer (requires debugger.mojo)')
  tracing_subparser = tracing_parser.add_subparsers(
      help='the command to run')

  start_tracing_parser = tracing_subparser.add_parser('start',
      help='start tracing')
  start_tracing_parser.set_defaults(func=_tracing_start)

  stop_tracing_parser = tracing_subparser.add_parser('stop',
      help='stop tracing and retrieve the result')
  stop_tracing_parser.add_argument('file_name', type=str, nargs='?',
      help='name of the output file (optional)')
  stop_tracing_parser.set_defaults(func=_tracing_stop)


def _wm_load(args):
  """Loads (embeds) the given url in the window manager."""
  if not _send_request('load', args.url):
    return 1
  return 0


def _add_wm_command(subparsers):
  """Sets up the parser for the 'wm' command."""
  wm_parser = subparsers.add_parser('wm', help='window manager (requires '
                                    'debugger.mojo)')
  wm_subparser = wm_parser.add_subparsers(
      help='the command to run')

  wm_load_parser = wm_subparser.add_parser('load',
      help='load (embed) the given url')
  wm_load_parser.add_argument('url', type=str,
      help='the url to load')
  wm_load_parser.set_defaults(func=_wm_load)


def _device_stack(args):
  """Runs the device logcat through android_stack_parser."""
  adb_path = args.adb_path if args.adb_path else 'adb'
  logcat_cmd = [adb_path, 'logcat', '-d']
  try:
    logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE)
  except OSError:
    print 'failed to call adb, make sure it is in PATH or pass --adb-path'
    return 1

  devtools_dir = os.path.dirname(os.path.abspath(__file__))
  stack_command = [os.path.join(devtools_dir, 'android_stack_parser', 'stack')]
  if args.build_dir:
    stack_command.append('--build-dir=' +
            os.path.abspath(','.join(args.build_dir)))
  if args.ndk_dir:
    stack_command.append('--ndk-dir=' + os.path.abspath(args.ndk_dir))
  stack_command.append('-')
  stack = subprocess.Popen(stack_command, stdin=logcat.stdout)

  logcat.wait()
  stack.wait()

  if logcat.returncode:
    print 'adb logcat failed, make sure the device is connected and available'
    return logcat.returncode
  if stack.returncode:
    return stack.returncode
  return 0


def _gdb_attach(args):
  """Run GDB on an instance of Mojo Shell on an android device."""
  if args.ndk_dir:
    ndk_dir = args.ndk_dir
  else:
    try:
      ndk_dir = os.path.join(_get_dir_above('third_party'), 'third_party',
                             'android_tools', 'ndk')
      if not os.path.exists(ndk_dir):
        raise DirectoryNotFoundException()
    except DirectoryNotFoundException:
      logging.fatal("Unable to find the Android NDK, please specify its path "
          "with --ndk-dir.")
      return

  install_args = {}
  if args.gsutil_dir:
    install_args['gsutil'] = os.path.join(args.gsutil_dir, 'gsutil')
  else:
    try:
      depot_tools_path = paths.find_depot_tools()
      if not depot_tools_path:
        raise DirectoryNotFoundException()
      install_args['gsutil'] = os.path.join(depot_tools_path, 'third_party',
                                            'gsutil', 'gsutil')
      if not os.path.exists(install_args['gsutil']):
        raise DirectoryNotFoundException()
    except DirectoryNotFoundException:
      logging.fatal("Unable to find gsutil, please specify its path with "
                    "--gsutil-dir.")
      return

  if args.adb_path:
    install_args['adb'] = args.adb_path
  else:
    install_args['adb'] = 'adb'

  try:
    install(**install_args)
  except OSError as e:
    if e.errno == 2:
      # ADB not found in path, print an error message
      logging.fatal("Unable to find ADB, please specify its path with "
                    "--adb-path.")
      return
    else:
      raise

  gdb_path = os.path.join(
      ndk_dir,
      'toolchains',
      # TODO(etiennej): Always select the most recent toolchain?
      'arm-linux-androideabi-4.9',
      'prebuilt',
      # TODO(etiennej): DEPS mac NDK and use it on macs.
      'linux-x86_64',
      'bin',
      'arm-linux-androideabi-gdb')
  python_gdb_script_path = os.path.join(os.path.dirname(__file__),
                                        'android_gdb', 'session.py')
  debug_session_arguments = {}
  if args.build_dir:
    debug_session_arguments["build_directory_list"] = ','.join(args.build_dir)
  else:
    try:
      debug_session_arguments["build_directory_list"] = os.path.join(
          _get_dir_above('out'), 'out', 'android_Debug')
      if not os.path.exists(debug_session_arguments["build_directory_list"]):
        raise DirectoryNotFoundException()
    except DirectoryNotFoundException:
      logging.fatal("Unable to find the build directory, please specify it "
                    "using --build-dir.")
      return

  if args.package_name:
    debug_session_arguments["package_name"] = args.package_name
  else:
    debug_session_arguments["package_name"] = _DEFAULT_PACKAGE_NAME
  debug_session_arguments['adb'] = install_args['adb']
  if args.pyelftools_dir:
    debug_session_arguments["pyelftools_dir"] = args.pyelftools_dir
  else:
    try:
      debug_session_arguments["pyelftools_dir"] = os.path.join(
          _get_dir_above('third_party'), 'third_party', 'pyelftools')
      if not os.path.exists(debug_session_arguments["pyelftools_dir"]):
        raise DirectoryNotFoundException()
    except DirectoryNotFoundException:
      logging.fatal("Unable to find pyelftools python module, please specify "
          "its path using --pyelftools-dir.")
      return

  debug_session_arguments_str = ', '.join(
      [k + '="' + codecs.encode(v, 'string_escape') + '"'
       for k, v in debug_session_arguments.items()])

  # We need to pass some commands to GDB at startup.
  gdb_commands_file = tempfile.NamedTemporaryFile()
  gdb_commands_file.write('source ' + python_gdb_script_path + '\n')
  gdb_commands_file.write('py d = DebugSession(' + debug_session_arguments_str
                          + ')\n')
  gdb_commands_file.write('py d.start()\n')
  gdb_commands_file.flush()

  gdb_proc = subprocess.Popen([gdb_path, '-x', gdb_commands_file.name],
                              stdin=sys.stdin,
                              stdout=sys.stdout,
                              stderr=sys.stderr)

  # We don't want SIGINT to stop this program. It is automatically propagated by
  # the system to gdb.
  signal.signal(signal.SIGINT, signal.SIG_IGN)
  gdb_proc.wait()
  signal.signal(signal.SIGINT, signal.SIG_DFL)


def _add_device_command(subparsers):
  """Sets up the parser for the 'device' command."""
  device_parser = subparsers.add_parser('device',
      help='interact with the Android device (requires adb in PATH or passing '
           '--adb-path)')
  device_parser.add_argument('--adb-path', type=str,
      help='path to the adb tool from the Android SDK (optional)')
  device_subparser = device_parser.add_subparsers(
      help='the command to run')

  device_stack_parser = device_subparser.add_parser('stack',
      help='symbolize the crash stacktraces from the device log')
  device_stack_parser.add_argument('--ndk-dir', type=str,
      help='path to the directory containing the Android NDK')
  device_stack_parser.add_argument('--build-dir', type=str, action='append',
      help='paths to the build directory, may be repeated')
  device_stack_parser.set_defaults(func=_device_stack)


def _add_gdb_command(subparsers):
  gdb_parser = subparsers.add_parser(
      'gdb', help='Debug Mojo Shell and its apps using GDB')
  gdb_subparser = gdb_parser.add_subparsers(
      help='Commands to GDB')

  gdb_attach_parser = gdb_subparser.add_parser(
      'attach', help='Attach GDB to a running Mojo Shell process')
  gdb_attach_parser.add_argument('--adb-path', type=str,
      help='path to the adb tool from the Android SDK (optional)')
  gdb_attach_parser.add_argument('--ndk-dir', type=str,
      help='path to the directory containing the Android NDK')
  gdb_attach_parser.add_argument('--build-dir', type=str, action='append',
      help='Paths to the build directory, may be repeated')
  gdb_attach_parser.add_argument('--pyelftools-dir', type=str,
      help='Path to a directory containing third party libraries')
  gdb_attach_parser.add_argument('--gsutil-dir', type=str,
      help='Path to a directory containing gsutil')
  gdb_attach_parser.add_argument('--package-name', type=str,
      help='Name of the Mojo Shell android package to debug')
  gdb_attach_parser.set_defaults(func=_gdb_attach)


def main():
  parser = argparse.ArgumentParser(description='Command-line interface for '
                                                'mojo:debugger')
  subparsers = parser.add_subparsers(help='the tool to run')
  _add_device_command(subparsers)
  _add_tracing_command(subparsers)
  _add_wm_command(subparsers)
  _add_gdb_command(subparsers)

  args = parser.parse_args()
  return args.func(args)

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