#!/usr/bin/env python3
# Copyright (C) 2012 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""A utility script for starting and stopping the web socket server with the
   same configuration as used in the layout tests."""

import logging
import optparse
import tempfile

from webkitpy.common.host import Host
from webkitpy.layout_tests.servers.websocket_server import PyWebSocket
from webkitpy.port import platform_options


def main():
    option_parser = optparse.OptionParser()
    option_parser.add_option('--server', type='choice',
                             choices=['start', 'stop'], default='start',
                             help='Server action (start|stop).')
    option_parser.add_option('-p', '--port', dest='port',
                             default=None, help='Port to listen on.')
    option_parser.add_option('-r', '--root',
                             help='Absolute path to DocumentRoot '
                                  '(overrides layout test roots).')
    option_parser.add_option('-t', '--tls', dest='use_tls',
                             action='store_true',
                             default=False, help='use TLS (wss://).')
    option_parser.add_option('-k', '--private_key', dest='private_key',
                             default='', help='TLS private key file.')
    option_parser.add_option('-c', '--certificate', dest='certificate',
                             default='', help='TLS certificate file.')
    option_parser.add_option('--ca-certificate', dest='ca_certificate',
                             default='', help='TLS CA certificate file for '
                                              'client authentication.')
    option_parser.add_option('--chromium', action='store_true',
                             dest='chromium',
                             default=False,
                             help='Use the Chromium port.')
    option_parser.add_option('--register_cygwin', action="store_true",
                             dest="register_cygwin",
                             help='Register Cygwin paths (on Win try bots).')
    option_parser.add_option('--pidfile', help='path to pid file.')
    option_parser.add_option('--output-dir', dest='output_dir',
                             default=None, help='output directory.')
    option_parser.add_option('-v', '--verbose', action='store_true',
                             default=False,
                             help='Include debug-level logging.')

    option_group = optparse.OptionGroup(option_parser, "Platform options")
    option_group.add_options(platform_options())
    option_parser.add_option_group(option_group)

    options, args = option_parser.parse_args()

    if not options.port:
        if options.use_tls:
            options.port = PyWebSocket.DEFAULT_WSS_PORT
        else:
            options.port = PyWebSocket.DEFAULT_WS_PORT

    if not options.output_dir:
        options.output_dir = tempfile.gettempdir()

    kwds = {'port': options.port, 'use_tls': options.use_tls}
    if options.root:
        kwds['root'] = options.root
    if options.private_key:
        kwds['private_key'] = options.private_key
    if options.certificate:
        kwds['certificate'] = options.certificate
    if options.ca_certificate:
        kwds['ca_certificate'] = options.ca_certificate
    if options.pidfile:
        kwds['pidfile'] = options.pidfile

    host = Host()
    port_obj = host.port_factory.get(options.platform, options=options)
    pywebsocket = PyWebSocket(port_obj, options.output_dir, **kwds)

    log_level = logging.WARN
    if options.verbose:
        log_level = logging.DEBUG
    logging.basicConfig(level=log_level)

    if 'start' == options.server:
        pywebsocket.start()
    else:
        pywebsocket.stop()

if '__main__' == __name__:
    main()
