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

# pylint: disable=R0201




import logging
import sys

from devil.android import device_errors
from devil.android.valgrind_tools import base_tool


def SetChromeTimeoutScale(device, scale):
  """Sets the timeout scale in /data/local/tmp/chrome_timeout_scale to scale."""
  path = '/data/local/tmp/chrome_timeout_scale'
  if not scale or scale == 1.0:
    # Delete if scale is None/0.0/1.0 since the default timeout scale is 1.0
    device.RemovePath(path, force=True, as_root=True)
  else:
    device.WriteFile(path, '%f' % scale, as_root=True)



class AddressSanitizerTool(base_tool.BaseTool):
  """AddressSanitizer tool."""

  WRAPPER_NAME = '/system/bin/asanwrapper'
  # Disable memcmp overlap check.There are blobs (gl drivers)
  # on some android devices that use memcmp on overlapping regions,
  # nothing we can do about that.
  EXTRA_OPTIONS = 'strict_memcmp=0,use_sigaltstack=1'

  def __init__(self, device):
    super().__init__()
    self._device = device

  @classmethod
  def CopyFiles(cls, device):
    """Copies ASan tools to the device."""
    del device

  def GetTestWrapper(self):
    return AddressSanitizerTool.WRAPPER_NAME

  def GetUtilWrapper(self):
    """Returns the wrapper for utilities, such as forwarder.

    AddressSanitizer wrapper must be added to all instrumented binaries,
    including forwarder and the like. This can be removed if such binaries
    were built without instrumentation. """
    return self.GetTestWrapper()

  def SetupEnvironment(self):
    try:
      self._device.EnableRoot()
    except device_errors.CommandFailedError as e:
      # Try to set the timeout scale anyway.
      # TODO(jbudorick) Handle this exception appropriately after interface
      #                 conversions are finished.
      logging.error(str(e))
    SetChromeTimeoutScale(self._device, self.GetTimeoutScale())

  def CleanUpEnvironment(self):
    SetChromeTimeoutScale(self._device, None)

  def GetTimeoutScale(self):
    # Very slow startup.
    return 20.0


TOOL_REGISTRY = {
    'asan': AddressSanitizerTool,
}


def CreateTool(tool_name, device):
  """Creates a tool with the specified tool name.

  Args:
    tool_name: Name of the tool to create.
    device: A DeviceUtils instance.
  Returns:
    A tool for the specified tool_name.
  """
  if not tool_name:
    return base_tool.BaseTool()

  ctor = TOOL_REGISTRY.get(tool_name)
  if ctor:
    return ctor(device)
  print('Unknown tool %s, available tools: %s' %
        (tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))))
  sys.exit(1)


def PushFilesForTool(tool_name, device):
  """Pushes the files required for |tool_name| to |device|.

  Args:
    tool_name: Name of the tool to create.
    device: A DeviceUtils instance.
  """
  if not tool_name:
    return

  clazz = TOOL_REGISTRY.get(tool_name)
  if clazz:
    clazz.CopyFiles(device)
  else:
    print('Unknown tool %s, available tools: %s' % (tool_name, ', '.join(
        sorted(TOOL_REGISTRY.keys()))))
    sys.exit(1)
