#!/usr/bin/python

# Copyright (C) 2005, 2006, 2007, 2015 Apple Inc.  All rights reserved.
# Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
# Copyright (C) 2011 Research In Motion Limited. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer. 
# 2.  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. 
# 3.  Neither the name of Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.

import optparse
import subprocess
import sys
import tempfile
import time

from webkitpy.common.host import Host
from webkitpy.layout_tests.servers import web_platform_test_server
from webkitpy.port import platform_options

def parse_args(args):
    parser = optparse.OptionParser()
    parser.add_option("-a", "--all-interfaces", help="Bind to all interfaces", action="store_true", dest="http_all_interfaces")
    parser.add_option("-p", "--port", help="Bind to port NNNN", action="store", type="int", dest="http_port")
    parser.add_option("--no-httpd", help="Do not start httpd server", action="store_false", default=True, dest="httpd_server")
    parser.add_option("--no-wpt", help="Do not start web-platform-tests server", action="store_false", default=True, dest="web_platform_test_server")
    return parser.parse_args(args)

def main(argv, stdout, stderr):
    options, args = parse_args(argv)
    host = Host()

    log_file = tempfile.NamedTemporaryFile()
    options.http_access_log = log_file.name
    options.http_error_log = log_file.name
    options.platform = None

    try:
        port = host.port_factory.get(options.platform, options)
    except NotImplementedError, e:
        print >> stderr, str(e)
        return EXCEPTIONAL_EXIT_STATUS

    if options.web_platform_test_server:
        print "Starting web-platform-tests server on <%s>" % web_platform_test_server.base_url(port)
        port.start_web_platform_test_server()

    if options.httpd_server:
        # FIXME(154294): somehow retrieve the actual ports and interfaces bound by the httpd server
        http_port = options.http_port if options.http_port is not None else "8000"
        if options.http_all_interfaces is not None:
            print "Starting httpd on port %s (all interfaces)" % http_port
        else:
            print "Starting httpd on <http://127.0.0.1:%s>" % http_port

        port.start_http_server()
        port.start_websocket_server()

    try:
        tail = subprocess.Popen(['tail', '-F', log_file.name], stdout=subprocess.PIPE)
        while True:
            sys.stdout.write(tail.stdout.readline())
    except KeyboardInterrupt:
        if options.web_platform_test_server:
            port.stop_web_platform_test_server()
        if options.httpd_server:
            port.stop_websocket_server()
            port.stop_http_server()


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:], sys.stdout, sys.stderr))
