# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This module has common mock objects and functions used in unit tests for
# mobly.controllers.android_device module.

from builtins import bytes

import logging
import mock
import os

DEFAULT_MOCK_PROPERTIES = {
    'ro.build.id': 'AB42',
    'ro.build.type': 'userdebug',
    'ro.build.fingerprint': 'FakeModel:Dessert/AB42/1234567:userdebug/dev-keys',
    'ro.build.product': 'FakeModel',
    'ro.build.version.codename': 'Z',
    'ro.build.version.incremental': '1234567',
    'ro.build.version.sdk': '28',
    'ro.product.name': 'FakeModel',
    'ro.debuggable': '1',
    'sys.boot_completed': "1",
    'ro.build.characteristics': 'emulator,phone',
    'ro.hardware': 'marlin',
}


class Error(Exception):
  pass


def get_mock_ads(num):
  """Generates a list of mock AndroidDevice objects.

  The serial number of each device will be integer 0 through num - 1.

  Args:
    num: An integer that is the number of mock AndroidDevice objects to
      create.
  """
  ads = []
  for i in range(num):
    ad = mock.MagicMock(name="AndroidDevice", serial=str(i), h_port=None)
    ad.skip_logcat = False
    ads.append(ad)
  return ads


def get_all_instances():
  return get_mock_ads(5)


def get_instances(serials):
  ads = []
  for serial in serials:
    ad = mock.MagicMock(name="AndroidDevice", serial=serial, h_port=None)
    ads.append(ad)
  return ads


def get_instances_with_configs(dicts):
  return get_instances([d['serial'] for d in dicts])


def list_adb_devices():
  return [ad.serial for ad in get_mock_ads(5)]


class MockAdbProxy:
  """Mock class that swaps out calls to adb with mock calls."""

  def __init__(self,
               serial='',
               fail_br=False,
               fail_br_before_N=False,
               mock_properties=None,
               installed_packages=None,
               instrumented_packages=None):
    self.serial = serial
    self.fail_br = fail_br
    self.fail_br_before_N = fail_br_before_N
    self.getprops_call_count = 0
    if mock_properties is None:
      self.mock_properties = DEFAULT_MOCK_PROPERTIES.copy()
    else:
      self.mock_properties = mock_properties
    if installed_packages is None:
      installed_packages = []
    self.installed_packages = installed_packages
    if instrumented_packages is None:
      instrumented_packages = []
    self.installed_packages = installed_packages
    self.instrumented_packages = instrumented_packages

  def shell(self, params, timeout=None):
    if params == "id -u":
      return b"root"
    elif params == "bugreportz":
      if self.fail_br:
        return b"OMG I died!\n"
      return b'OK:/path/bugreport.zip\n'
    elif params == "bugreportz -v":
      if self.fail_br_before_N:
        return b"/system/bin/sh: bugreportz: not found"
      return b'1.1'
    elif 'pm list package' in params:
      packages = self.installed_packages + [
          package for package, _, _ in self.instrumented_packages
      ]
      return bytes('\n'.join(['package:%s' % package for package in packages]),
                   'utf-8')
    elif 'pm list instrumentation' in params:
      return bytes(
          '\n'.join([
              'instrumentation:%s/%s (target=%s)' % (package, runner, target)
              for package, runner, target in self.instrumented_packages
          ]), 'utf-8')
    elif 'which' in params:
      return b''

  def getprop(self, params):
    if params in self.mock_properties:
      return self.mock_properties[params]

  def getprops(self, params):
    self.getprops_call_count = self.getprops_call_count + 1
    return self.mock_properties

  def bugreport(self, args, shell=False, timeout=None):
    expected = os.path.join(
        logging.log_path, 'AndroidDevice%s' % self.serial, 'BugReports',
        'bugreport,test_something,%s,fakemodel,sometime' % self.serial)
    if expected not in args:
      raise Error('"Expected "%s", got "%s"' % (expected, args))

  def __getattr__(self, name):
    """All calls to the none-existent functions in adb proxy would
    simply return the adb command string.
    """

    def adb_call(*args, **kwargs):
      arg_str = ' '.join(str(elem) for elem in args)
      return arg_str

    return adb_call


class MockFastbootProxy:
  """Mock class that swaps out calls to adb with mock calls."""

  def __init__(self, serial):
    self.serial = serial

  def devices(self):
    return b"xxxx device\nyyyy device"

  def __getattr__(self, name):

    def fastboot_call(*args):
      arg_str = ' '.join(str(elem) for elem in args)
      return arg_str

    return fastboot_call
