from typing import List, Any
import pandas as pd
import boto3
import logging
import awswrangler as wr

import great_expectations as ge
from great_expectations.core.batch import Batch, BatchRequest, RuntimeBatchRequest
from great_expectations.profile.user_configurable_profiler import UserConfigurableProfiler
from psi_great_expectations.contextor import build_data_context_config
from psi_great_expectations import get_logger, log_it
from great_expectations.checkpoint import SimpleCheckpoint, Checkpoint

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


class DataValidator():
    def __init__(
        self,
        data_name: str,
        bucket: str,
        prefix: str,
        logger: logging.Logger = None,
        aws_session: 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)
        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
