
from bz2 import compress
import gzip
#import ujson
#import orjson
import ujson
from azure.storage.blob import BlobServiceClient, BlobClient
import time
import pandas as pd
import zipfile
from io import BytesIO

def GB_get_db_stream(connection, container, file_name):
    blob_client = BlobClient.from_connection_string(connection, container, file_name)
    return blob_client.download_blob()

def GB_get_db_bytes(connection, container, file_name):
    stream = GB_get_db_stream(connection, container, file_name)
    return stream.readall()    

def GB_get_db_json(connection, container, file_name):
    jo_bytes = GB_get_db_bytes(connection, container, file_name)
    #jo_str = jo_bytes.decode('utf8')
    return ujson.loads(jo_bytes) #json.loads(jo_bytes)

# def GB_get_db_orjson(connection, container, file_name):
#     jo_bytes = GB_get_db_bytes(connection, container, file_name)
#     #jo_str = jo_bytes.decode('utf8')
#     return orjson.loads(jo_bytes) 

# def GB_get_db_ujson(connection, container, file_name):
#     jo_bytes = GB_get_db_bytes(connection, container, file_name)
    
#     #jo_str = jo_bytes.decode('utf8')
    
#     return ujson.loads(jo_bytes) 

def GB_get_db_compressed(connection, container, file_name):
    jo_bytes = GB_get_db_bytes(connection, container, file_name)
    
    #jo_str = jo_bytes.decode('utf8')
    
    json_data = gzip.decompress(jo_bytes)     
    return ujson.loads(json_data) 

def GB_set_db_json(connection, container, file_name, json_data):
    blob_client = BlobServiceClient.from_connection_string(connection)
    container_client = blob_client.get_container_client(container=container)
    container_client.upload_blob(file_name, json_data, overwrite=True)
    return None


def GB_upload_bytes(connection, container, file_name, bytes, compress=False):
    blob_client = BlobServiceClient.from_connection_string(connection)
    container_client = blob_client.get_container_client(container=container)
    
    if not container_client.exists():
        container_client.create_container()   
    
    container_client.upload_blob(file_name, bytes.getvalue(), overwrite=True)
    return None

def GB_upload_json(connection, container, file_name, json_data, compress=False):
    blob_client = BlobServiceClient.from_connection_string(connection)
    container_client = blob_client.get_container_client(container=container)
    
    if not container_client.exists():
        container_client.create_container()   
         
    if compress:
        json_data = gzip.compress(json_data.encode('utf-8'))     
        
    container_client.upload_blob(file_name, json_data, overwrite=True)
    return None

def GB_upload_file(connection, container, file_name, FQName, encoding=None):

    blob_client = BlobServiceClient.from_connection_string(connection)
    container_client = blob_client.get_container_client(container=container)
    
    if not container_client.exists():
        container_client.create_container() 
        
    if encoding==None:
        with open(FQName) as f:
            container_client.upload_blob(file_name, f.read(), overwrite=True)
    else:
        with open(FQName, encoding=encoding) as f:
            container_client.upload_blob(file_name, f.read(), overwrite=True)   
    return None

def GB_upload_file_from_stream(connection, container, file_name, fileStream):

    blob_client = BlobServiceClient.from_connection_string(connection)
    container_client = blob_client.get_container_client(container=container)
    
    if not container_client.exists():
        container_client.create_container() 
        
    container_client.upload_blob(file_name, fileStream, overwrite=True)
    
    return None

def GB_upload_excel_file(connection, container, file_name, FQName):

    blob_client = BlobServiceClient.from_connection_string(connection)
    container_client = blob_client.get_container_client(container=container)
    
    if not container_client.exists():
        container_client.create_container() 
        
    with open(FQName, mode="rb") as data:
        container_client.upload_blob(file_name, data=data, overwrite=True)
    
    return None

def GB_file_exists(connection, container, file_name):
    blob_client = BlobClient.from_connection_string(connection, container, file_name)
    return blob_client.exists()

    #Danger! Danger!
def GB_destroy_container(connection, container):
    blob_client = BlobServiceClient.from_connection_string(connection)
    container_client = blob_client.get_container_client(container=container)
    if container_client.exists():
        container_client.delete_container()
        
def GB_destroy_file(connection, container, file_name):
    blob_client = BlobClient.from_connection_string(connection, container, file_name)
    blob_client.delete_blob()
    
def GB_destroy_multiple_files(connection, container, search_str):
    blob_client = BlobServiceClient.from_connection_string(connection)
    container_client = blob_client.get_container_client(container=container)
    file_list = container_client.list_blobs(name_starts_with = search_str)
    
    
    for blob in file_list:
        # start = time.time()
        if search_str in blob.name:
            GB_destroy_file(connection, container, blob.name)
        # seconds = time.time() - start
        # print(seconds)
        pass
        
    return None
    
    


def GB_container_exists(connection, container):
    blob_client = BlobServiceClient.from_connection_string(connection)
    container_client = blob_client.get_container_client(container=container)
    return container_client.exists()

def GB_container_list(connection):
    blob_client = BlobServiceClient.from_connection_string(connection)
    return blob_client.list_containers()

def GB_file_list(connection_str, containerID, search_str = None):
    blob_client = BlobServiceClient.from_connection_string(connection_str)
    container_client = blob_client.get_container_client(container=containerID)
    file_list = container_client.list_blobs(name_starts_with = search_str)
    blobList=[]
    for blob in file_list:
        blobList.append(blob.name)
    return blobList

def GB_copy_file(connection_str, containerID, original_file_name, new_file_name):
    blob_client = BlobServiceClient.from_connection_string(connection_str)
    container_client = blob_client.get_container_client(container=containerID)
    # original = GB_get_db_bytes(connection_str, containerID, original_file_name)
    original = container_client.download_blob(original_file_name).readall()
    # GB_upload_bytes(connection_str, containerID, original_file_name, original)
    container_client.upload_blob(new_file_name, original, overwrite=True)
    
def GB_copy_folder(connection_str, containerID, original_folder_name, new_folder_name):
    #assuming account name is the second item. May not always be true.
    account_name = connection_str.split(';')[1].split('=')[1] 
    blob_client = BlobServiceClient.from_connection_string(connection_str)
    container_client = blob_client.get_container_client(container=containerID)
    # original = GB_get_db_bytes(connection_str, containerID, original_file_name)
    file_list = container_client.list_blobs(name_starts_with = original_folder_name)
    blobList = []
    for blob in file_list:
        original_file_name = blob.name
        new_file_name = new_folder_name+'/'+'/'.join(blob.name.split('/')[1:])
        source_blob = (f"https://{account_name}.blob.core.windows.net/{containerID}/{original_file_name}")

        copied_blob = blob_client.get_blob_client(containerID, new_file_name)
        copied_blob.start_copy_from_url(source_blob)
    pass

def GB_extract_file(connection_str, origin_containerID, original_file_name, updated_containerID, new_location):
    blob_client = BlobServiceClient.from_connection_string(connection_str)
    container_client = blob_client.get_container_client(container=origin_containerID)
    b = container_client.download_blob(original_file_name)
    original = b.readall()
    
    fp = BytesIO(original)
    zfp = zipfile.ZipFile(fp, "r")
    for name in zfp.namelist():
        zip_file = zfp.read(name)
        container_client = blob_client.get_container_client(container=updated_containerID)
        container_client.upload_blob(new_location+name, zip_file, overwrite=True)
    
def GB_last_modified(connection_str, containerID, file_name):
    blob_client = BlobClient.from_connection_string(connection_str, containerID, file_name)
    return blob_client.get_blob_properties()['last_modified']

def GB_last_modified_list(connection_str, containerID, search_str):
    blob_client = BlobServiceClient.from_connection_string(connection_str)
    container_client = blob_client.get_container_client(container=containerID)
    file_list = container_client.list_blobs(name_starts_with = search_str)
    blobList=[]
    for blob in file_list:
        if search_str in blob.name:
            blobList.append(blob['last_modified'])
    return blobList

