"""GCP credentials subclass of urgap's IOCreds submodule."""

import logging

from typing import ParamSpec

import google.api_core.exceptions
import google_crc32c

from google import auth
from google.cloud import secretmanager

from urgap.ucredentials.io._base import IOBaseCreds

P = ParamSpec("P")
logger = logging.getLogger(__name__)


class IOGCPCreds(IOBaseCreds):
    """IO class interface GCP."""

    def __init__(self, **kwargs: P.kwargs) -> None:
        """Create new IOGCPCreds class."""
        super().__init__(**kwargs)
        self.version_id = kwargs["version_id"]
        self.project_id = kwargs["project_id"]

    def get_secret(self) -> str:
        """Get secret from GCP secret Manager.

        Code adapted from:
        https://github.com/googleapis/python-secret-manager/blob/897cffe09ad97915f4b70617be839136de1416f4/samples/snippets/access_secret_version.py

        Returns:
            Secret from GCP secret Manager.
        """
        # Import the Secret Manager client library.
        secret = None
        client = None
        response = None

        try:
            client = secretmanager.SecretManagerServiceClient()
            response = client.access_secret_version(
                request={
                    "name": f"projects/{self.project_id}/secrets/{self.secret_id}/versions/{self.version_id}",
                },
            )
        except (
            auth.exceptions.DefaultCredentialsError,
            google.api_core.exceptions.PermissionDenied,
        ):
            logging.warning("Secret could not be retrieved from GCP.")

        if client is not None and response is not None:
            # Verify payload checksum.
            crc32c = google_crc32c.Checksum()
            crc32c.update(response.payload.data)
            if response.payload.data_crc32c != int(crc32c.hexdigest(), 16):
                msg = f"Secret {self.secret_id} payload is corrupted."
                logger.warning(msg)

            secret = response.payload.data.decode("UTF-8")
        return secret
