import sys
import os


test_filename = sys.argv[1]
del sys.argv[1]



from gevent import monkey
# Only test the default set of patch arguments.
monkey.patch_all()

from .patched_tests_setup import disable_tests_in_source
from . import support
from . import resources
from . import SkipTest
from . import util



# This uses the internal built-in function ``_thread._count()``,
# which we don't/can't monkey-patch, so it returns inaccurate information.
def threading_setup():
    return (1, ())

# This then tries to wait for that value to return to its original value;
# but if we started worker threads that can never happen.
def threading_cleanup(*_args):
    return

assert support.threading_setup
assert support.threading_cleanup

support.threading_setup = threading_setup
support.threading_cleanup = threading_cleanup


# On all versions of Python 3.6+, this also uses ``_thread._count()``,
# meaning it suffers from inaccuracies,
# and test_socket.py constantly fails with an extra thread
# on some random test. We disable it entirely.
# XXX: Figure out how to make a *definition* in ./support.py actually
# override the original in test.support, without having to
# manually set it
#
import contextlib
@contextlib.contextmanager
def wait_threads_exit(timeout=None): # pylint:disable=unused-argument
    # On <  3.10, this is support.wait_threads_exit;
    # on >= 3.10, this is threading_helper.wait_threads_exit
    yield

support.wait_threads_exit = wait_threads_exit

# On Python 3.11, they changed the way that they deal with this,
# meaning that this method no longer works. (Actually, it's not
# clear that any of our patches to `support` are doing anything on
# Python 3 at all? They certainly aren't on 3.11). This was a good
# thing As it led to adding the timeout value for the threadpool
# idle threads. But...the default of 5s meant that many tests in
# test_socket were each taking at least 5s to run, leading to the
# whole thing exceeding the allowed test timeout. We could set the
# GEVENT_THREADPOOL_IDLE_TASK_TIMEOUT env variable to a smaller
# value, and although that might stress the system nicely, it's
# not indicative of what end users see. And it's still hard to get
# a correct value.
#
# So try harder to make sure our patches apply.
#
# If this fails, symptoms are very long running tests that can be resolved
# by setting that TASK_TIMEOUT value small, and/or setting GEVENT_RESOLVER=block.
# Also, some number of warnings about dangling threads, or failures
# from wait_threads_exit
try:
    from test import support as ts
except ImportError:
    ts = None
else:
    ts.threading_setup = threading_setup
    ts.threading_cleanup = threading_cleanup
    ts.wait_threads_exit = wait_threads_exit
    ts.print_warning = lambda msg: msg

try:
    from test.support import threading_helper
except ImportError:
    pass
else:
    threading_helper.wait_threads_exit = wait_threads_exit
    threading_helper.threading_setup = threading_setup
    threading_helper.threading_cleanup = threading_cleanup


try:
    from test.support import import_helper
except ImportError:
    pass
else:
    # Importing fresh modules breaks our monkey patches. we can't allow that.
    def import_fresh_module(name, *_args, **_kwargs):
        import importlib
        return importlib.import_module(name)
    import_helper.import_fresh_module = import_fresh_module

# So we don't have to patch test_threading to use our
# version of lock_tests, we patch
from gevent.tests import lock_tests
try:
    import test.lock_tests
except ImportError:
    pass
else:
    test.lock_tests = lock_tests
    sys.modules['tests.lock_tests'] = lock_tests

# Configure allowed resources
resources.setup_resources()

if not os.path.exists(test_filename) and os.sep not in test_filename:
    # A simple filename, given without a path, that doesn't exist.
    # So we change to the appropriate directory, if we can find it.
    # This happens when copy-pasting the output of the testrunner
    for d in util.find_stdlib_tests():
        if os.path.exists(os.path.join(d, test_filename)):
            os.chdir(d)
            break

__file__ = os.path.abspath(test_filename) #os.path.join(os.getcwd(), test_filename)
test_name = os.path.splitext(os.path.basename(test_filename))[0]

print('Running with patch_all(): %s' % (__file__,))

with open(test_filename, encoding='utf-8') as module_file:
    module_source = module_file.read()
module_source = disable_tests_in_source(module_source, test_name)


# We write the module source to a file so that tracebacks
# show correctly, since disabling the tests changes line
# numbers. However, note that __file__ must still point to the
# real location so that data files can be found.
# See https://github.com/gevent/gevent/issues/1306
import tempfile
temp_handle, temp_path = tempfile.mkstemp(prefix=test_name, suffix='.py', text=True)
os.write(temp_handle, module_source.encode('utf-8'))
os.close(temp_handle)
remove_file = not os.environ.get('GEVENT_DEBUG')
if remove_file and ts is not None:
    # Some of the stdlib tests spew a lot of data to stdout. This
    # makes it hard to read results of a whole run of all the monkey
    # stdlib tests. The main CPython regression runner, the equivalent
    # of ``gevent.tests`` sets this to false and that stops some of it.
    ts.verbose = 0
    print('Disabling verbose stdlib tests')
try:
    module_code = compile(module_source,
                          temp_path,
                          'exec',
                          dont_inherit=True)
    exec(module_code, globals())
    remove_file = True
except SkipTest as e:
    remove_file = True
    # Some tests can raise test.support.ResourceDenied
    # in their main method before the testrunner takes over.
    # That's a kind of SkipTest. we can't get a true skip count because it
    # hasn't run, though.
    print(e)
    # Match the regular unittest output, including ending with skipped
    print("Ran 0 tests in 0.0s")
    print('OK (skipped=0)')
finally:
    if remove_file:
        try:
            os.remove(temp_path)
        except OSError:
            pass
