#!/usr/bin/python3


import os
import signal
import socket
import subprocess
import sys
import time
import unittest
import urllib.request


TESTS_DIR = os.path.dirname(__file__)
UWSGI_BINARY = "/usr/bin/uwsgi-core"
UWSGI_ADDR = "127.0.0.1"
UWSGI_PORT = 9090
UWSGI_HTTP = f"{UWSGI_ADDR}:{UWSGI_PORT}"


class UwsgiTest(unittest.TestCase):

    def start_server(self, args):
        self.testserver = subprocess.Popen(
            [UWSGI_BINARY] + args,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
        )

    def uwsgi_ready(self):
        try:
            s = socket.socket()
            s.connect(
                (
                    UWSGI_ADDR,
                    UWSGI_PORT,
                )
            )
        except socket.error:
            return False
        else:
            return True
        finally:
            s.close()

    def start_listen_server(self, args):
        self.start_server(["--http-socket", UWSGI_HTTP] + args)

        # ensure server is ready
        retries = 10
        while not self.uwsgi_ready() and retries > 0:
            time.sleep(0.1)
            retries = retries - 1
            if retries == 0:
                raise RuntimeError("uwsgi test server is not available")

    def tearDown(self):
        if hasattr(self._outcome, "errors"):
            # Python 3.4 - 3.10  (These two methods have no side effects)
            result = self.defaultTestResult()
            self._feedErrorsToResult(result, self._outcome.errors)
        else:
            # Python 3.11+
            result = self._outcome.result
        ok = not (result.errors + result.failures)

        self.testserver.send_signal(signal.SIGTERM)
        if not ok:
            print(self.testserver.stdout.read(), file=sys.stderr)

        self.testserver.wait()
        self.testserver.stdout.close()

    def test_python3_hello(self):
        self.start_listen_server(
            [
                "--plugin",
                "pypy3",
                "--pypy-lib",
                "/usr/lib/uwsgi/plugins/pypy/libpypy3-c.so",
                "--pypy-home",
                "/usr/lib/uwsgi/plugins/pypy/home",
                "--pypy-setup",
                "/usr/lib/uwsgi/plugins/pypy/pypy_setup.py",
                "--pypy-wsgi-file",
                os.path.join(TESTS_DIR, "hello.py"),
            ]
        )

        with urllib.request.urlopen(f"http://{UWSGI_HTTP}/") as r:
            self.assertEqual(r.read(), b"Hello World")


if __name__ == "__main__":
    unittest.main()
