# Copyright (C) 2013 Igalia S.L.
#
# 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 Igalia S.L. 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.

import logging
import re
import unittest

from webkitpy.common.system.filesystem_mock import MockFileSystem
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.common.system.systemhost_mock import MockSystemHost
from webkitpy.port import Port
from webkitpy.port.server_process_mock import MockServerProcess
from webkitpy.port.westondriver import WestonDriver
from webkitpy.tool.mocktool import MockOptions

_log = logging.getLogger(__name__)


class WestonXvfbDriverDisplayTest():
    def __init__(self, expected_xvfbdisplay):
        self._expected_xvfbdisplay = expected_xvfbdisplay

    def _xvfb_run(self, environment):
        return self._expected_xvfbdisplay


class WestonDriverTest(unittest.TestCase):
    def make_driver(self):
        port = Port(MockSystemHost(log_executive=True), 'westondrivertestport', options=MockOptions(configuration='Release'))
        port._config.build_directory = lambda configuration: "/mock_build"
        port._server_process_constructor = MockServerProcess

        driver = WestonDriver(port, worker_number=0, pixel_tests=True)
        driver._startup_delay_secs = 0
        driver._expected_xvfbdisplay = 23
        driver._xvfbdriver = WestonXvfbDriverDisplayTest(driver._expected_xvfbdisplay)
        driver._environment = port.setup_environ_for_server(port.driver_name())
        return driver

    def test_start(self):
        driver = self.make_driver()
        output_capture = OutputCapture()

        output_capture.capture_output()
        driver.start(pixel_tests=True, per_test_args=[])
        _, _, logs = output_capture.restore_output()

        self.assertTrue(re.match(r"MOCK popen: \['weston', '--socket=WKTesting-weston-[0-9a-f]{32}', '--width=1024', '--height=768', '--use-pixman'\], env=.*\n", logs), None)
        self.assertTrue(re.match(r"WKTesting-weston-[0-9a-f]{32}", driver._server_process.env['WAYLAND_DISPLAY']))
        self.assertFalse('DISPLAY' in driver._server_process.env)
        self.assertTrue("'DISPLAY': ':%s'" % driver._expected_xvfbdisplay in logs)
        self.assertEqual(driver._server_process.env['GDK_BACKEND'], 'wayland')
        self.assertTrue(driver._server_process.started)

        # This prevents improper cleanup of the subprocess.Popen mock object in implicitly-invoked WestonDriver.stop.
        driver._weston_process = None

    def test_stop(self):
        class FakeWestonProcess(object):
            def terminate(self):
                _log.info("MOCK FakeWestonProcess.terminate")

        driver = self.make_driver()
        driver._weston_process = FakeWestonProcess()

        expected_logs = "MOCK FakeWestonProcess.terminate\n"
        OutputCapture().assert_outputs(self, driver.stop, [], expected_logs=expected_logs)

        self.assertIsNone(driver._weston_process)
