{% extends '_base.py.j2' %}

{% block content %}

{% set package_path = api.naming.module_namespace|join('.') + "." + api.naming.versioned_module_name %}
from {{package_path}} import gapic_version as package_version

import google.api_core as api_core
import sys

__version__ = package_version.__version__

if sys.version_info >= (3, 8):  # pragma: NO COVER
    from importlib import metadata
else:  # pragma: NO COVER
    # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
    # this code path once we drop support for Python 3.7
    import importlib_metadata as metadata

{#  Import subpackages. -#}
{% for subpackage, _ in api.subpackages|dictsort %}
from . import {{ subpackage }}
{% endfor %}

{#  Import services for this package. -#}
{% for service in api.services.values()|sort(attribute='name')
        if service.meta.address.subpackage == api.subpackage_view %}
from .services.{{ service.name|snake_case }} import {{ service.client_name }}
{% if 'grpc' in opts.transport %}
from .services.{{ service.name|snake_case }} import {{ service.async_client_name }}
{% endif %}
{% endfor %}

{#  Import messages and enums from each proto.
    It is safe to import all of the messages into the same namespace here,
    because protocol buffers itself enforces selector uniqueness within
    a proto package.
-#}
{% for proto in api.protos.values()|sort(attribute='name')
        if proto.meta.address.subpackage == api.subpackage_view %}
{% for message in proto.messages.values()|sort(attribute='name') %}
from .types.{{ proto.module_name }} import {{ message.name }}
{% endfor %}
{% for enum in proto.enums.values()|sort(attribute='name') %}
from .types.{{ proto.module_name }} import {{ enum.name }}
{% endfor %}
{% endfor %}

if hasattr(api_core, "check_python_version") and hasattr(api_core, "check_dependency_versions"):   # pragma: NO COVER
    {# TODO(api_core): remove `type:ignore` below when minimum version of api_core makes the else clause unnecessary. #}
    api_core.check_python_version("{{package_path}}") # type: ignore
    api_core.check_dependency_versions("{{package_path}}") # type: ignore
else:   # pragma: NO COVER
{# TODO(api_core): Remove this try-catch when we require api-core at a version that
   supports the changes in https://github.com/googleapis/python-api-core/pull/832

    In the meantime, please ensure the functionality here mirrors the
    equivalent functionality in api_core, in those two functions above.
#}
    # An older version of api_core is installed which does not define the
    # functions above. We do equivalent checks manually.
    try:
        import warnings
        import sys

        _py_version_str = sys.version.split()[0]
        _package_label = "{{package_path}}"
        if sys.version_info < (3, 9):
            warnings.warn("You are using a non-supported Python version " +
                          f"({_py_version_str}).  Google will not post any further " +
                          f"updates to {_package_label} supporting this Python version. " +
                          "Please upgrade to the latest Python version, or at " +
                          f"least to Python 3.9, and then update {_package_label}.",
                          FutureWarning)
        if sys.version_info[:2] == (3, 9):
            warnings.warn(f"You are using a Python version ({_py_version_str}) " +
                          f"which Google will stop supporting in {_package_label} in " +
                          "January 2026. Please " +
                          "upgrade to the latest Python version, or at " +
                          "least to Python 3.10, before then, and " +
                          f"then update {_package_label}.",
                          FutureWarning)

        def parse_version_to_tuple(version_string: str):
            """Safely converts a semantic version string to a comparable tuple of integers.
            Example: "4.25.8" -> (4, 25, 8)
            Ignores non-numeric parts and handles common version formats.
            Args:
                version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
            Returns:
                Tuple of integers for the parsed version string.
            """
            parts = []
            for part in version_string.split("."):
                try:
                    parts.append(int(part))
                except ValueError:
                    # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
                    # This is a simplification compared to 'packaging.parse_version', but sufficient
                    # for comparing strictly numeric semantic versions.
                    break
            return tuple(parts)

        def _get_version(dependency_name):
            try:
                version_string: str = metadata.version(dependency_name)
                parsed_version = parse_version_to_tuple(version_string)
                return (parsed_version, version_string)
            except Exception:
                # Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
                # or errors during parse_version_to_tuple
                return (None, "--")

        _dependency_package = "google.protobuf"
        _next_supported_version = "4.25.8"
        _next_supported_version_tuple = (4, 25, 8)
        _recommendation = " (we recommend 6.x)"
        (_version_used, _version_used_string) = _get_version(_dependency_package)
        if _version_used and _version_used < _next_supported_version_tuple:
            warnings.warn(f"Package {_package_label} depends on " +
                          f"{_dependency_package}, currently installed at version " +
                          f"{_version_used_string}. Future updates to " +
                          f"{_package_label} will require {_dependency_package} at " +
                          f"version {_next_supported_version} or higher{_recommendation}." +
                          " Please ensure " +
                          "that either (a) your Python environment doesn't pin the " +
                          f"version of {_dependency_package}, so that updates to " +
                          f"{_package_label} can require the higher version, or " +
                          "(b) you manually update your Python environment to use at " +
                          f"least version {_next_supported_version} of " +
                          f"{_dependency_package}.",
                          FutureWarning)
    except Exception:
            warnings.warn("Could not determine the version of Python " +
                          "currently being used. To continue receiving " +
                          "updates for {_package_label}, ensure you are " +
                          "using a supported version of Python; see " +
                          "https://devguide.python.org/versions/")

{#  Define __all__.
    This requires the full set of imported names, so we iterate over
    them again.
-#}
__all__ = (
    {% filter sort_lines -%}
    {% for subpackage in api.subpackages -%}
    '{{ subpackage }}',
    {% endfor -%}
    {% for service in api.services.values()
            if service.meta.address.subpackage == api.subpackage_view -%}
    '{{ service.client_name }}',
    {% if 'grpc' in opts.transport %}
    '{{ service.async_client_name }}',
    {% endif %}
    {% endfor -%}
    {% for proto in api.protos.values()
            if proto.meta.address.subpackage == api.subpackage_view -%}
    {% for message in proto.messages.values()|sort(attribute='name') -%}
    '{{ message.name }}',
    {% endfor -%}
    {% for enum in proto.enums.values() -%}
    '{{ enum.name }}',
    {% endfor -%}
    {% endfor -%}
    {% endfilter %}
)
{% endblock %}
