# Copyright 2015 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.

"""Configures devil for use in chromium."""

import os
import sys

from pylib import constants
from pylib.constants import host_paths

if host_paths.DEVIL_PATH not in sys.path:
  sys.path.insert(1, host_paths.DEVIL_PATH)

from devil import devil_env
from devil.android.ndk import abis

_BUILD_DIR = os.path.join(constants.DIR_SOURCE_ROOT, 'build')
if _BUILD_DIR not in sys.path:
  sys.path.insert(1, _BUILD_DIR)

import gn_helpers

_DEVIL_CONFIG = os.path.abspath(
    os.path.join(os.path.dirname(__file__), 'devil_chromium.json'))

_DEVIL_BUILD_PRODUCT_DEPS = {
  'chromium_commands': [
    {
      'platform': 'linux2',
      'arch': 'x86_64',
      'path_components': ['lib.java', 'chromium_commands.dex.jar'],
    }
  ],
  'forwarder_device': [
    {
      'platform': 'android',
      'arch': abis.ARM,
      'path_components': ['forwarder_dist'],
    },
    {
      'platform': 'android',
      'arch': abis.ARM_64,
      'path_components': ['forwarder_dist'],
    },
    {
      'platform': 'android',
      'arch': 'mips',
      'path_components': ['forwarder_dist'],
    },
    {
      'platform': 'android',
      'arch': 'mips64',
      'path_components': ['forwarder_dist'],
    },
    {
      'platform': 'android',
      'arch': abis.X86,
      'path_components': ['forwarder_dist'],
    },
    {
      'platform': 'android',
      'arch': abis.X86_64,
      'path_components': ['forwarder_dist'],
    },
  ],
  'forwarder_host': [
    {
      'platform': 'linux2',
      'arch': 'x86_64',
      'path_components': ['host_forwarder'],
    },
  ],
  'md5sum_device': [
    {
      'platform': 'android',
      'arch': abis.ARM,
      'path_components': ['md5sum_dist'],
    },
    {
      'platform': 'android',
      'arch': abis.ARM_64,
      'path_components': ['md5sum_dist'],
    },
    {
      'platform': 'android',
      'arch': 'mips',
      'path_components': ['md5sum_dist'],
    },
    {
      'platform': 'android',
      'arch': 'mips64',
      'path_components': ['md5sum_dist'],
    },
    {
      'platform': 'android',
      'arch': abis.X86,
      'path_components': ['md5sum_dist'],
    },
    {
      'platform': 'android',
      'arch': abis.X86_64,
      'path_components': ['md5sum_dist'],
    },
  ],
  'md5sum_host': [
    {
      'platform': 'linux2',
      'arch': 'x86_64',
      'path_components': ['md5sum_bin_host'],
    },
  ],
}


def _UseLocalBuildProducts(output_directory, devil_dynamic_config):
  output_directory = os.path.abspath(output_directory)
  devil_dynamic_config['dependencies'] = {
      dep_name: {
          'file_info': {
              '%s_%s' % (dep_config['platform'], dep_config['arch']): {
                  'local_paths': [
                      os.path.join(output_directory,
                                   *dep_config['path_components']),
                  ],
              }
              for dep_config in dep_configs
          }
      }
      for dep_name, dep_configs in _DEVIL_BUILD_PRODUCT_DEPS.iteritems()
  }


def _BuildWithChromium():
  """Returns value of gclient's |build_with_chromium|."""
  gni_path = os.path.join(_BUILD_DIR, 'config', 'gclient_args.gni')
  if not os.path.exists(gni_path):
    return False
  with open(gni_path) as f:
    data = f.read()
  args = gn_helpers.FromGNArgs(data)
  return args.get('build_with_chromium', False)


def Initialize(output_directory=None, custom_deps=None, adb_path=None):
  """Initializes devil with chromium's binaries and third-party libraries.

  This includes:
    - Libraries:
      - the android SDK ("android_sdk")
    - Build products:
      - host & device forwarder binaries
          ("forwarder_device" and "forwarder_host")
      - host & device md5sum binaries ("md5sum_device" and "md5sum_host")

  Args:
    output_directory: An optional path to the output directory. If not set,
      no built dependencies are configured.
    custom_deps: An optional dictionary specifying custom dependencies.
      This should be of the form:

        {
          'dependency_name': {
            'platform': 'path',
            ...
          },
          ...
        }
    adb_path: An optional path to use for the adb binary. If not set, this uses
      the adb binary provided by the Android SDK.
  """
  build_with_chromium = _BuildWithChromium()

  devil_dynamic_config = {
    'config_type': 'BaseConfig',
    'dependencies': {},
  }
  if build_with_chromium and output_directory:
    # Non-chromium users of chromium's //build directory fetch build products
    # from google storage rather than use locally built copies. Chromium uses
    # locally-built copies so that changes to the tools can be easily tested.
    _UseLocalBuildProducts(output_directory, devil_dynamic_config)

  if custom_deps:
    devil_dynamic_config['dependencies'].update(custom_deps)
  if adb_path:
    devil_dynamic_config['dependencies'].update({
      'adb': {
        'file_info': {
          devil_env.GetPlatform(): {
            'local_paths': [adb_path]
          }
        }
      }
    })

  config_files = [_DEVIL_CONFIG] if build_with_chromium else None
  devil_env.config.Initialize(configs=[devil_dynamic_config],
                              config_files=config_files)
