# Copyright 2012 The Chromium Authors
# 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)
