#!/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 _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_gdb_command(subparsers)

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

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