#!/usr/bin/env python

#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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 division
from __future__ import print_function
import time
import socket
import subprocess
import sys
import os
import signal
from optparse import OptionParser

parser = OptionParser()
parser.add_option('--genpydirs', type='string', dest='genpydirs',
    default='default,slots,newstyle,newstyleslots,dynamic,dynamicslots',
    help='directory extensions for generated code, used as suffixes for \"gen-py-*\" added sys.path for individual tests')
parser.add_option("--port", type="int", dest="port", default=9090,
    help="port number for server to listen on")
parser.add_option('-v', '--verbose', action="store_const",
    dest="verbose", const=2,
    help="verbose output")
parser.add_option('-q', '--quiet', action="store_const",
    dest="verbose", const=0,
    help="minimal output")
parser.set_defaults(verbose=1)
options, args = parser.parse_args()

generated_dirs = []
for gp_dir in options.genpydirs.split(','):
  generated_dirs.append('gen-py-%s' % (gp_dir))

SCRIPTS = ['TSimpleJSONProtocolTest.py',
           'SerializationTest.py',
           'TestEof.py',
           'TestSyntax.py',
           'TestSocket.py']
FRAMED = ["TNonblockingServer"]
SKIP_ZLIB = ['TNonblockingServer', 'THttpServer']
SKIP_SSL = ['TNonblockingServer', 'THttpServer']
EXTRA_DELAY = dict(TProcessPoolServer=5.5)

PROTOS= [
    'accel',
    'binary',
    'compact',
    'json']

SERVERS = [
  "TSimpleServer",
  "TThreadedServer",
  "TThreadPoolServer",
  "TProcessPoolServer", # new!
  "TForkingServer",
  "TNonblockingServer",
  "THttpServer" ]

# Test for presence of multiprocessing module, and if it is not present, then
# remove it from the list of available servers.
try:
  import multiprocessing
except:
  print('Warning: the multiprocessing module is unavailable. Skipping tests for TProcessPoolServer')
  SERVERS.remove('TProcessPoolServer')

try:
  import ssl
except:
  print('Warning, no ssl module available. Skipping all SSL tests.')
  SKIP_SSL.extend(SERVERS)

# commandline permits a single class name to be specified to override SERVERS=[...]
if len(args) == 1:
  if args[0] in SERVERS:
    SERVERS = args
  else:
    print('Unavailable server type "%s", please choose one of: %s' % (args[0], SERVERS))
    sys.exit(0)


def relfile(fname):
    return os.path.join(os.path.dirname(__file__), fname)

def runScriptTest(genpydir, script):
  script_args = [sys.executable, relfile(script) ]
  script_args.append('--genpydir=%s' % genpydir)
  serverproc = subprocess.Popen(script_args)
  print('\nTesting script: %s\n----' % (' '.join(script_args)))
  ret = subprocess.call(script_args)
  if ret != 0:
    raise Exception("Script subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(script_args)))

def runServiceTest(genpydir, server_class, proto, port, use_zlib, use_ssl):
  # Build command line arguments
  server_args = [sys.executable, relfile('TestServer.py') ]
  cli_args = [sys.executable, relfile('TestClient.py') ]
  for which in (server_args, cli_args):
    which.append('--genpydir=%s' % genpydir)
    which.append('--protocol=%s' % proto) # accel, binary or compact
    which.append('--port=%d' % port) # default to 9090
    if use_zlib:
      which.append('--zlib')
    if use_ssl:
      which.append('--ssl')
    if options.verbose == 0:
      which.append('-q')
    if options.verbose == 2:
      which.append('-v')
  # server-specific option to select server class
  server_args.append(server_class)
  # client-specific cmdline options
  if server_class in FRAMED:
    cli_args.append('--transport=framed')
  else:
     cli_args.append('--transport=buffered')
  if server_class == 'THttpServer':
    cli_args.append('--http=/')
  if options.verbose > 0:
    print('Testing server %s: %s' % (server_class, ' '.join(server_args)))
  serverproc = subprocess.Popen(server_args)

  def ensureServerAlive():
    if serverproc.poll() is not None:
      print(('FAIL: Server process (%s) failed with retcode %d')
             % (' '.join(server_args), serverproc.returncode))
      raise Exception('Server subprocess %s died, args: %s'
                      % (server_class, ' '.join(server_args)))

  # Wait for the server to start accepting connections on the given port.
  sock = socket.socket()
  sleep_time = 0.1  # Seconds
  max_attempts = 100
  try:
    attempt = 0
    while sock.connect_ex(('127.0.0.1', port)) != 0:
      attempt += 1
      if attempt >= max_attempts:
        raise Exception("TestServer not ready on port %d after %.2f seconds"
                        % (port, sleep_time * attempt))
      ensureServerAlive()
      time.sleep(sleep_time)
  finally:
    sock.close()

  try:
    if options.verbose > 0:
      print('Testing client: %s' % (' '.join(cli_args)))
    ret = subprocess.call(cli_args)
    if ret != 0:
      raise Exception("Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args)))
  finally:
    # check that server didn't die
    ensureServerAlive()
    extra_sleep = EXTRA_DELAY.get(server_class, 0)
    if extra_sleep > 0 and options.verbose > 0:
      print('Giving %s (proto=%s,zlib=%s,ssl=%s) an extra %d seconds for child'
             'processes to terminate via alarm'
             % (server_class, proto, use_zlib, use_ssl, extra_sleep))
      time.sleep(extra_sleep)
    os.kill(serverproc.pid, signal.SIGKILL)
    serverproc.wait()

test_count = 0
# run tests without a client/server first
print('----------------')
print(' Executing individual test scripts with various generated code directories')
print(' Directories to be tested: ' + ', '.join(generated_dirs))
print(' Scripts to be tested: ' + ', '.join(SCRIPTS))
print('----------------')
for genpydir in generated_dirs:
  for script in SCRIPTS:
    runScriptTest(genpydir, script)

print('----------------')
print(' Executing Client/Server tests with various generated code directories')
print(' Servers to be tested: ' + ', '.join(SERVERS))
print(' Directories to be tested: ' + ', '.join(generated_dirs))
print(' Protocols to be tested: ' + ', '.join(PROTOS))
print(' Options to be tested: ZLIB(yes/no), SSL(yes/no)')
print('----------------')
for try_server in SERVERS:
  for genpydir in generated_dirs:
    for try_proto in PROTOS:
      for with_zlib in (False, True):
        # skip any servers that don't work with the Zlib transport
        if with_zlib and try_server in SKIP_ZLIB:
          continue
        for with_ssl in (False, True):
          # skip any servers that don't work with SSL
          if with_ssl and try_server in SKIP_SSL:
            continue
          test_count += 1
          if options.verbose > 0:
            print('\nTest run #%d:  (includes %s) Server=%s,  Proto=%s,  zlib=%s,  SSL=%s' % (test_count, genpydir, try_server, try_proto, with_zlib, with_ssl))
          runServiceTest(genpydir, try_server, try_proto, options.port, with_zlib, with_ssl)
          if options.verbose > 0:
            print('OK: Finished (includes %s)  %s / %s proto / zlib=%s / SSL=%s.   %d combinations tested.' % (genpydir, try_server, try_proto, with_zlib, with_ssl, test_count))
