# Copyright 2017 The Cobalt Authors. All Rights Reserved.
#
# 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.


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import importlib
import logging
import random
import socket
import sys
import unittest

import _env  # pylint: disable=unused-import
from cobalt.black_box_tests import black_box_cobalt_runner
from cobalt.tools.automated_testing import cobalt_runner
from proxy_server import ProxyServer
from starboard.tools import abstract_launcher
from starboard.tools import build

_PORT_SELECTION_RETRY_LIMIT = 10
_PORT_SELECTION_RANGE = [5000, 7000]
_SERVER_EXIT_TIMEOUT_SECONDS = 30
# These tests can only be run on platforms whose app launcher can send suspend/
# resume signals.
_TESTS_NEEDING_SYSTEM_SIGNAL = [
    'cancel_sync_loads_when_suspended',
    'preload_font',
    'preload_visibility',
    'signal_handler_doesnt_crash',
    'suspend_visibility',
    'timer_hit_after_preload',
    'timer_hit_in_preload',
]
# These tests only need app launchers with webdriver.
_TESTS_NO_SIGNAL = [
    'allow_eval',
    'disable_eval_with_csp',
    'persistent_cookie',
    'web_debugger',
    'web_platform_tests',
]
# Location of test files.
_TEST_DIR_PATH = 'cobalt.black_box_tests.tests.'
# Platform dependent device parameters.
_device_params = None
# Binding address used to create the test server.
_binding_address = None
# Port used to create the web platform test http server.
_wpt_http_port = None


class BlackBoxTestCase(unittest.TestCase):

  def __init__(self, *args, **kwargs):
    super(BlackBoxTestCase, self).__init__(*args, **kwargs)
    self.device_params = _device_params
    self.platform_config = build.GetPlatformConfig(_device_params.platform)
    self.cobalt_config = self.platform_config.GetApplicationConfiguration(
        'cobalt')

  @classmethod
  def setUpClass(cls):
    super(BlackBoxTestCase, cls).setUpClass()
    print('Running ' + cls.__name__)

  @classmethod
  def tearDownClass(cls):
    super(BlackBoxTestCase, cls).tearDownClass()
    print('Done ' + cls.__name__)

  def CreateCobaltRunner(self, url, target_params=None):
    all_target_params = list(target_params) if target_params else []
    if _device_params.target_params is not None:
      all_target_params += _device_params.target_params
    new_runner = black_box_cobalt_runner.BlackBoxCobaltRunner(
        device_params=_device_params, url=url, target_params=all_target_params)
    return new_runner

  def GetBindingAddress(self):
    return _binding_address

  def GetWptHttpPort(self):
    return _wpt_http_port


def LoadTests(platform, config, device_id, out_directory):
  launcher = abstract_launcher.LauncherFactory(
      platform,
      'cobalt',
      config,
      device_id=device_id,
      target_params=None,
      output_file=None,
      out_directory=out_directory)

  if launcher.SupportsSuspendResume():
    test_targets = _TESTS_NEEDING_SYSTEM_SIGNAL + _TESTS_NO_SIGNAL
  else:
    test_targets = _TESTS_NO_SIGNAL

  test_suite = unittest.TestSuite()
  for test in test_targets:
    test_suite.addTest(unittest.TestLoader().loadTestsFromModule(
        importlib.import_module(_TEST_DIR_PATH + test)))
  return test_suite


class BlackBoxTests(object):
  """Helper class to run all black box tests and return results."""

  def __init__(self, server_binding_address, proxy_address=None,
               proxy_port=None, test_name=None, wpt_http_port=None):
    logging.basicConfig(level=logging.DEBUG)

    # Setup global variables used by test cases
    global _device_params
    _device_params = cobalt_runner.GetDeviceParamsFromCommandLine()
    # Keep other modules from seeing these args
    sys.argv = sys.argv[:1]
    global _binding_address
    _binding_address = server_binding_address
    # Port used to create the web platform test http server. If not specified,
    # a random free port is used.
    if wpt_http_port is None:
      wpt_http_port = str(self.GetUnusedPort([server_binding_address]))
    global _wpt_http_port
    _wpt_http_port = wpt_http_port
    _device_params.target_params.append(
        '--web-platform-test-server=http://web-platform.test:%s' %
        wpt_http_port)

    # Port used to create the proxy server. If not specified, a random free
    # port is used.
    if proxy_port is None:
      proxy_port = str(self.GetUnusedPort([server_binding_address]))
    if proxy_address is None:
      proxy_address = server_binding_address
    _device_params.target_params.append('--proxy=%s:%s' %
                                        (proxy_address, proxy_port))

    self.proxy_port = proxy_port
    self.test_name = test_name

    # Test domains used in web platform tests to be resolved to the server
    # binding address.
    hosts = [
        'web-platform.test',
        'www.web-platform.test',
        'www1.web-platform.test',
        'www2.web-platform.test',
        'xn--n8j6ds53lwwkrqhv28a.web-platform.test',
        'xn--lve-6lad.web-platform.test'
    ]
    self.host_resolve_map = dict([(host, server_binding_address) for host in hosts])

  def Run(self):
    if self.proxy_port == '-1':
      return 1
    logging.info('Using proxy port: %s', self.proxy_port)

    with ProxyServer(port=self.proxy_port,
                     host_resolve_map=self.host_resolve_map):
      if self.test_name:
        suite = unittest.TestLoader().loadTestsFromModule(
            importlib.import_module(_TEST_DIR_PATH + self.test_name))
      else:
        suite = LoadTests(_device_params.platform, _device_params.config,
                          _device_params.device_id,
                          _device_params.out_directory)
      return_code = not unittest.TextTestRunner(
          verbosity=0, stream=sys.stdout).run(suite).wasSuccessful()
      return return_code

  def GetUnusedPort(self, addresses):
    """Find a free port on the list of addresses by pinging with sockets."""
    SOCKET_SUCCESS = 0

    if not addresses:
      logging.error('Can not find unused port on invalid addresses.')
      return -1

    socks = []
    for address in addresses:
      socks.append((address, socket.socket(socket.AF_INET, socket.SOCK_STREAM)))
    try:
      for _ in range(_PORT_SELECTION_RETRY_LIMIT):
        port = random.randint(_PORT_SELECTION_RANGE[0], _PORT_SELECTION_RANGE[1])
        unused = True
        for sock in socks:
          result = sock[1].connect_ex((sock[0], port))
          if result == SOCKET_SUCCESS:
            ununsed = False
            break
        if unused:
          return port
      logging.error(
          'Can not find unused port on addresses within %s attempts.' %
          _PORT_SELECTION_RETRY_LIMIT)
      return -1
    finally:
      for sock in socks:
        sock[1].close()


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('--server_binding_address',
                      default='127.0.0.1',
                      help='Binding address used to create the test server.')
  parser.add_argument('--proxy_address',
                      default=None,
                      help=('Address to the proxy server that all black box'
                            'tests are run through. If not specified, the'
                            'server binding address is used.'))
  parser.add_argument('--proxy_port',
                      default=None,
                      help=('Port used to create the proxy server that all'
                            'black box tests are run through. If not'
                            'specified, a random free port is used.'))
  parser.add_argument('--test_name',
                      default=None,
                      help=('Name of test to be run. If not specified, all '
                            'tests are run.'))
  parser.add_argument('--wpt_http_port',
                      default=None,
                       help=('Port used to create the web platform test http'
                             'server. If not specified, a random free port is'
                             'used.'))
  args, _ = parser.parse_known_args()

  test_object = BlackBoxTests(args.server_binding_address, args.proxy_address,
                              args.proxy_port, args.test_name,
                              args.wpt_http_port)
  sys.exit(test_object.Run())


if __name__ == '__main__':
  # Running this script on the command line and importing this file are
  # different and create two modules.
  # Import this module to ensure we are using the same module as the tests to
  # make module-owned variables like device_param accessible to the tests.
  main_module = importlib.import_module(
      'cobalt.black_box_tests.black_box_tests')
  sys.exit(main_module.main())
