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

from __future__ import absolute_import
import json
import time

from six.moves import range  # pylint: disable=redefined-builtin
from devil.android import forwarder
from devil.android import ports
from pylib.base import test_server
from pylib.constants import host_paths

with host_paths.SysPath(host_paths.BUILD_COMMON_PATH):
  import chrome_test_server_spawner


# The tests should not need more than one test server instance.
MAX_TEST_SERVER_INSTANCES = 1


def _WaitUntil(predicate, max_attempts=5):
  """Blocks until the provided predicate (function) is true.

  Returns:
    Whether the provided predicate was satisfied once (before the timeout).
  """
  sleep_time_sec = 0.025
  for _ in range(1, max_attempts):
    if predicate():
      return True
    time.sleep(sleep_time_sec)
    sleep_time_sec = min(1, sleep_time_sec * 2)  # Don't wait more than 1 sec.
  return False


class PortForwarderAndroid(chrome_test_server_spawner.PortForwarder):
  def __init__(self, device, tool):
    self.device = device
    self.tool = tool

  def Map(self, port_pairs):
    forwarder.Forwarder.Map(port_pairs, self.device, self.tool)

  def GetDevicePortForHostPort(self, host_port):
    return forwarder.Forwarder.DevicePortForHostPort(host_port)

  def WaitHostPortAvailable(self, port):
    return _WaitUntil(lambda: ports.IsHostPortAvailable(port))

  def WaitPortNotAvailable(self, port):
    return _WaitUntil(lambda: not ports.IsHostPortAvailable(port))

  def WaitDevicePortReady(self, port):
    return _WaitUntil(lambda: ports.IsDevicePortUsed(self.device, port))

  def Unmap(self, device_port):
    forwarder.Forwarder.UnmapDevicePort(device_port, self.device)


class LocalTestServerSpawner(test_server.TestServer):

  def __init__(self, port, device, tool):
    super(LocalTestServerSpawner, self).__init__()
    self._device = device
    self._spawning_server = chrome_test_server_spawner.SpawningServer(
        port, PortForwarderAndroid(device, tool), MAX_TEST_SERVER_INSTANCES)
    self._tool = tool

  @property
  def server_address(self):
    return self._spawning_server.server.server_address

  @property
  def port(self):
    return self.server_address[1]

  #override
  def SetUp(self):
    # See net/test/spawned_test_server/remote_test_server.h for description of
    # the fields in the config file.
    test_server_config = json.dumps({
      'spawner_url_base': 'http://localhost:%d' % self.port
    })
    self._device.WriteFile(
        '%s/net-test-server-config' % self._device.GetExternalStoragePath(),
        test_server_config)
    forwarder.Forwarder.Map(
        [(self.port, self.port)], self._device, self._tool)
    self._spawning_server.Start()

  #override
  def Reset(self):
    self._spawning_server.CleanupState()

  #override
  def TearDown(self):
    self.Reset()
    self._spawning_server.Stop()
    forwarder.Forwarder.UnmapDevicePort(self.port, self._device)
