# Copyright 2013 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 logging
import os
import sys

from telemetry.internal.backends.chrome import android_browser_finder
from telemetry.internal.platform import profiler

# Environment variables to (android properties, default value) mapping.
_ENV_VARIABLES = {
  'HEAP_PROFILE_TIME_INTERVAL': ('heapprof.time_interval', 20),
  'HEAP_PROFILE_MMAP': ('heapprof.mmap', 1),
  'DEEP_HEAP_PROFILE': ('heapprof.deep_heap_profile', 1),
}


class _TCMallocHeapProfilerAndroid(object):
  """An internal class to set android properties and fetch dumps from device."""

  _DEFAULT_DEVICE_DIR = '/data/local/tmp/heap'

  def __init__(self, browser_backend, output_path):
    self._browser_backend = browser_backend
    self._output_path = output_path

    _ENV_VARIABLES['HEAPPROFILE'] = ('heapprof',
        os.path.join(self._DEFAULT_DEVICE_DIR, 'dmprof'))

    self._SetDeviceProperties(_ENV_VARIABLES)

  def _SetDeviceProperties(self, properties):
    device_configured = False
    # This profiler requires adb root to set properties.
    try:
      self._browser_backend.device.EnableRoot()
    except:
      logging.exception('New exception caused by DeviceUtils conversion')
      raise
    for values in properties.itervalues():
      device_property = self._browser_backend.device.GetProp(values[0])
      if not device_property or not device_property.strip():
        self._browser_backend.device.SetProp(values[0], values[1])
        device_configured = True
    if not self._browser_backend.device.FileExists(
        self._DEFAULT_DEVICE_DIR):
      self._browser_backend.device.RunShellCommand(
          'mkdir -p ' + self._DEFAULT_DEVICE_DIR)
      self._browser_backend.device.RunShellCommand(
          'chmod 777 ' + self._DEFAULT_DEVICE_DIR)
      device_configured = True
    if device_configured:
      raise Exception('Device required special config, run again.')

  def CollectProfile(self):
    try:
      self._browser_backend.device.PullFile(
          self._DEFAULT_DEVICE_DIR, self._output_path)
    except:
      logging.exception('New exception caused by DeviceUtils conversion')
      raise
    self._browser_backend.device.RunShellCommand(
        'rm ' + os.path.join(self._DEFAULT_DEVICE_DIR, '*'))
    if os.path.exists(self._output_path):
      logging.info('TCMalloc dumps pulled to %s', self._output_path)
      with file(os.path.join(self._output_path,
                             'browser.pid'), 'w') as pid_file:
        pid_file.write(str(self._browser_backend.pid).rjust(5, '0'))
    return [self._output_path]


class _TCMallocHeapProfilerLinux(object):
  """An internal class to set environment variables and fetch dumps."""

  _DEFAULT_DIR = '/tmp/tcmalloc/'

  def __init__(self, browser_backend):
    self._browser_backend = browser_backend
    _ENV_VARIABLES['HEAPPROFILE'] = ('heapprof', self._DEFAULT_DIR + 'dmprof')
    self._CheckEnvironmentVariables(_ENV_VARIABLES)

  def _CheckEnvironmentVariables(self, env_vars):
    msg = ''
    for key, values in env_vars.iteritems():
      if key not in os.environ:
        msg += '%s=%s ' % (key, str(values[1]))
    if msg:
      raise Exception('Need environment variables, try again with:\n %s' % msg)
    if not os.path.exists(os.environ['HEAPPROFILE']):
      os.makedirs(os.environ['HEAPPROFILE'])
    assert os.path.isdir(os.environ['HEAPPROFILE']), 'HEAPPROFILE is not a dir'

  def CollectProfile(self):
    with file(os.path.join(os.path.dirname(os.environ['HEAPPROFILE']),
                           'browser.pid'), 'w') as pid_file:
      pid_file.write(str(self._browser_backend.pid))
    print 'TCMalloc dumps available ', os.environ['HEAPPROFILE']
    return [os.environ['HEAPPROFILE']]


class TCMallocHeapProfiler(profiler.Profiler):
  """A Factory to instantiate the platform-specific profiler."""
  def __init__(self, browser_backend, platform_backend, output_path, state):
    super(TCMallocHeapProfiler, self).__init__(
        browser_backend, platform_backend, output_path, state)
    if platform_backend.GetOSName() == 'android':
      self._platform_profiler = _TCMallocHeapProfilerAndroid(
          browser_backend, output_path)
    else:
      self._platform_profiler = _TCMallocHeapProfilerLinux(browser_backend)

  @classmethod
  def name(cls):
    return 'tcmalloc-heap'

  @classmethod
  def is_supported(cls, browser_type):
    if browser_type.startswith('cros'):
      return False
    if sys.platform.startswith('linux'):
      return True
    if browser_type == 'any':
      return android_browser_finder.CanFindAvailableBrowsers()
    return browser_type.startswith('android')

  @classmethod
  def CustomizeBrowserOptions(cls, browser_type, options):
    options.AppendExtraBrowserArgs('--no-sandbox')
    options.AppendExtraBrowserArgs('--enable-memory-benchmarking')

  @classmethod
  def WillCloseBrowser(cls, browser_backend, platform_backend):
    # The tcmalloc_heap_profiler dumps files at regular
    # intervals (~20 secs).
    # This is a minor optimization to ensure it'll dump the last file when
    # the test completes.
    for i in xrange(len(browser_backend.browser.tabs)):
      browser_backend.browser.tabs[i].ExecuteJavaScript("""
        if (chrome && chrome.memoryBenchmarking) {
          chrome.memoryBenchmarking.heapProfilerDump('renderer', 'final');
          chrome.memoryBenchmarking.heapProfilerDump('browser', 'final');
        }
      """)

  def CollectProfile(self):
    return self._platform_profiler.CollectProfile()
