# This test script was automatically generated by the contrib-patch-tests.py
# script. If you want to make changes to it, you should make sure that you have
# removed the ``_generated`` suffix from the file name, to prevent the content
# from being overwritten by future re-generations.
import os
import subprocess
import sys

from ddtrace.contrib.internal.psycopg.patch import get_version
from ddtrace.contrib.internal.psycopg.patch import get_versions
from ddtrace.contrib.internal.psycopg.patch import patch


try:
    from ddtrace.contrib.internal.psycopg.patch import unpatch
except ImportError:
    unpatch = None
from tests.contrib.patch import PatchTestCase
from tests.contrib.patch import emit_integration_and_version_to_test_agent


class TestPsycopgPatch(PatchTestCase.Base):
    __integration_name__ = "psycopg"
    __module_name__ = "psycopg2"
    __patch_func__ = patch
    __unpatch_func__ = unpatch
    __get_version__ = get_version
    __get_versions__ = get_versions

    def assert_module_patched(self, psycopg):
        pass

    def assert_not_module_patched(self, psycopg):
        pass

    def assert_not_module_double_patched(self, psycopg):
        pass

    def test_and_emit_get_version(self):
        patch()
        assert get_version() == ""
        versions = get_versions()
        assert versions.get("psycopg2")
        emit_integration_and_version_to_test_agent("psycopg", versions["psycopg2"], "psycopg2")
        unpatch()

    def test_psycopg_circular_import_fix(self):
        fixture_path = os.path.join(os.path.dirname(__file__), "fixtures", "reproduce_psycopg_cyclic_import_error.py")

        env = os.environ.copy()
        codebase_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
        env["PYTHONPATH"] = os.pathsep.join([codebase_root, env.get("PYTHONPATH", "")])

        # Run the reproduction script with ddtrace-run
        # Note: tried with @run_in_subprocess but that fails to reproduce the error in the affected version
        # (v3.10.2) for some reason while running the separate script works.
        result = subprocess.run(
            [sys.executable, "-m", "ddtrace.commands.ddtrace_run", "python", fixture_path],
            capture_output=True,
            text=True,
            env=env,
            timeout=30,
        )

        full_output = result.stdout + result.stderr
        if "failed to enable ddtrace support for psycopg: partially initialized module" in full_output:
            self.fail("Circular import issue detected: the original bug is present and should be fixed")
        elif "psycopg2" in full_output and "ImportError" in full_output:
            self.skipTest("psycopg2 not available for testing")
        elif result.returncode != 0:
            self.fail(
                f"Reproduction script failed unexpectedly: "
                f"returncode={result.returncode}, stdout={result.stdout}, stderr={result.stderr}"
            )
