#  (c) cavaliba.com - data - filestore.py
# v3.19

import uuid
import hashlib

from app_home.configuration import get_configuration
from app_data.models import DataFile


#  single
def uuid_to_queryset(fileid):
    if not fileid:
        return
    return DataFile.objects.filter(fileid=fileid).first()

# list
def uuids_to_queryset(vlist):
    if not vlist:
        return
    return DataFile.objects.filter(fileid__in=vlist)


def uuids_to_filenames(vlist):
    return [i.filename for i in uuids_to_queryset(vlist)]


def uuid_to_filepath(fileid):
    rootdir =  get_configuration(appname="env", keyname="CAVALIBA_FILESTORE")
    return rootdir + fileid



def tmp_local_filepath():
    ''' tmp file don't exist un DataFile ; cleanup as orphans'''
    rootdir =  get_configuration(appname="env", keyname="CAVALIBA_FILESTORE")
    tmpid = 'tmp-'+str(uuid.uuid4()) 
    return rootdir + tmpid
    


def datafile_from_uploaded(file_uploaded):
    """
    Upload a file to filestore, create corresponding DataFile object 

    Args:
        file_uploaded:  Django request.FILES POST uploaded_file object

    Returns:
        Datafile: Datafile object with file written to filestore
    """

    if not file_uploaded:
        return



    df = DataFile()
    df.fileid = str(uuid.uuid4())              # f5fd12d3-a65a-4cf8-b3c1-22059ea3cbd5
    df.filename = file_uploaded.name
    df.filepath = uuid_to_filepath(df.fileid)
    df.displayname = file_uploaded.name
    df.size = file_uploaded.size
    df.save()

    # write uploaded file to filestore

    sig = hashlib.md5()

    with open(df.filepath, "wb+") as destination:
        if file_uploaded.multiple_chunks():
            # django chunked file (from /tmp)
            for chunk in file_uploaded.chunks():
                sig.update(chunk)
                destination.write(chunk)
        else:
            # in-memory
            full = file_uploaded.read()
            sig.update(full)
            destination.write(full)

    #  hash
    df.hash = str(sig.hexdigest())
    df.save()

    return df




