import csv
import io
from datetime import datetime
from typing import List

import boto3
from botocore.client import Config
from configmanager import configManager




config =Config(connect_timeout=9999)


class read_s3:
    def __intit__(self):
        self.configmng= configManager()
        self.s3_resoyurce= boto3.resource('s3', aws_access_key_id='',
                                    aws_secret_access_key='',
                                    region_name='us-east-1', config=config)

    def rename_file_on_s3(full_input_file_path, target_file_path, 
                            target_bucket_same=True, target_bucket_name : str=None):
                      
                            
        bucket_name = target_bucket_name if target_bucket_name else full_input_file_path.split('//')[1].split('/', 1)[0]
        file_path = full_input_file_path.split('//')[1].split('/', 1)[1]

        original_obj = s3_resource_bt.Object(bucket_name, file_path)

        target_obj = s3_resource_bt.Object(target_bucket_name, target_file_path)

        target_obj.put(Body=original_obj.get()['Body'].read())
        print("renamed file to ", target_file_path)


    def delete_file_on_s3(full_input_file_path):
        bucket_name = full_input_file_path.split('//')[1].split('/', 1)[0]
        file_path = full_input_file_path.split('//')[1].split('/', 1)[1]
        self.s3_resource.Object(bucket_name, file_path).delete()
        print('deleted temp file', file_path)



    def split_s3_full_path(s3_path):
        path_parts = s3_path.replace("s3://", "").split("/")
        bucket = path_parts.pop(0)
        key = "/".join(path_parts)
        return bucket, key


    def list_s3_files(bucket_name, bucket_path, file_name_wildcard):
        file_name_wildcard = file_name_wildcard.split('*')[0]
        file_name_wildcard = file_name_wildcard.split('/')[-1]

        
        bucket = self.s3_resource.Bucket(bucket_name)
        list_of_files = []
        for object_summary in bucket.objects.filter(Prefix=bucket_path):
            if file_name_wildcard in object_summary.key:
                list_of_files.append(object_summary.key)
        return list_of_files

    def update_tables_with_new_partitions(database , table, partition_values, s3_path):
        import boto3
        client = boto3.client("athena", aws_access_key_id="",
                            aws_secret_access_key="", region_name="us-east-1")

        
        try:
            update_query_response = client.start_query_execution(
                QueryString="ALTER TABLE {} ADD PARTITION ({});".format(table_name, partition_values),
                QueryExecutionContext={
                    'Database': database
                },
                ResultConfiguration={
                    'OutputLocation': s3_path
                }
            )
        except Exception as e:
            raise e
        print("updated partitions for table {} : {}!".format(table_name, full_date))

    def run_athena_query(query, db, output_path):
        each_query_response = athena_client_bt.start_query_execution(
            QueryString=query,
            QueryExecutionContext={
                'Database': db
            },
            ResultConfiguration={
                'OutputLocation': output_path,
            }
        )
        query_id = each_query_response['QueryExecutionId']
        i = 0
        while True:
            i += 1

            if i > 10:
                time.sleep(10)
            else:
                time.sleep(2)
            each_query_execution_status = athena_client_bt.get_query_execution(
                QueryExecutionId=query_id)

            if each_query_execution_status['QueryExecution']['Status']['State'] == 'SUCCEEDED':
                print("SUCCEEDED")
                output_file_name = each_query_execution_status['QueryExecution']['ResultConfiguration'][
                    'OutputLocation']
                return output_file_name
            elif each_query_execution_status['QueryExecution']['Status']['State'] in ('FAILED', 'CANCELLED'):
                print("FAILED/CANCELLED", query_id)
                raise Exception("FAILED/CANCELLED{}".format(query_id))
            else:
                continue
