import logging
from typing import Any, Optional

import boto3

from psi_great_expectations.contextor import build_data_context_config
from psi_great_expectations import get_logger, log_it

WEBOOK = "https://hooks.slack.com/services/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"


class DataValidator:
    def __init__(
        self,
        data_name: str,
        bucket: str,
        prefix: Optional[str] = None,
        base_public_path: Optional[str] = None,
        logger: Optional[logging.Logger] = None,
        aws_session: Optional[Any] = None,
    ):
        self.__data_name = data_name
        self.__bucket = bucket
        self.__prefix = prefix
        self.__logger = logger or get_logger()
        self.__aws_session = aws_session or boto3.Session()
        self.__suite = f"{self.__data_name}-suite"
        self.__checkpoint_name = f"{self.__data_name}-cp"
        self.__context = build_data_context_config(data_name, bucket, prefix, base_public_path)
        self.__checkpoint = self._build_checkpoint()

    @log_it
    def _build_checkpoint(self):
        checkpoint_config = {
            "name": self.__checkpoint_name,
            "config_version": 2,
            "module_name": "great_expectations.checkpoint",
            "class_name": "Checkpoint",
            "run_name_template": f"%Y%m%d-%H%M%S-{self.__checkpoint_name}",
            "action_list": [
                {
                    "name": "store_validation_result",
                    "action": {"class_name": "StoreValidationResultAction"},
                },
                {
                    "name": "store_evaluation_params",
                    "action": {"class_name": "StoreEvaluationParametersAction"},
                },
                {
                    "name": "update_data_docs",
                    "action": {"class_name": "UpdateDataDocsAction", "site_names": []},
                },
                {
                    "name": "send_slack_notification_on_validation_result",
                    "action": {
                        "class_name": "SlackNotificationAction",
                        "slack_webhook": WEBOOK,
                        "notify_on": "all",
                        "renderer": {
                            "module_name": "great_expectations.render.renderer.slack_renderer",
                            "class_name": "SlackRenderer",
                        },
                    },
                },
            ],
            "validations": [
                {
                    "batch_request": {
                        "datasource_name": self.__data_name,
                        "data_connector_name": "default_runtime_data_connector_name",
                        "data_asset_name": f"{self.__data_name}-dan",
                    },
                    "expectation_suite_name": self.__suite,
                }
            ],
        }

        self.__context.add_checkpoint(**checkpoint_config)

    @log_it
    def _run_validation(self, df: object):
        result = self.__context.run_checkpoint(
            checkpoint_name=self.__checkpoint_name,
            batch_request={
                "runtime_parameters": {"batch_data": df},
                "batch_identifiers": {"default_identifier_name": "default_identifier_name"},
            },
        )

        return result
