import random
import string
import datetime
from pathlib import Path
from fileTools import uniqueSecureFilename

def shape(x):
    if isinstance(x,list) or isinstance(x,tuple):
        return [shape(t) for t in x]
    elif isinstance(x,dict):
        return {t:shape(x[t]) for t in x}
    elif hasattr(x,'shape'):
        return x.shape
    elif hasattr(x,'__len__'):
        return x.__len__()
    return type(x)

def show(*args):
    for x in args:
        print(x)
        if not isinstance(x, str): print(shape(x))

def size(x):
    from pympler.asizeof import asizeof
    return f"{asizeof(x)/1024/1024} Mb"

def tensor_to_ndarray(obj):
    import torch
    if isinstance(obj, torch.Tensor):
        obj = obj.cpu().numpy()
    return obj

def is_int(s):
    import re
    pattern = re.compile(r"^[+-]?\d+$") # match optional sign and one or more digits
    return bool(pattern.match(s)) # return True if match, False otherwise

def limitLenStr(text, maxLen=20):
    limitText=text
    if len(limitText) > maxLen: limitText=f"...{limitText[(len(limitText)-maxLen):]}"
    return limitText

def randomString(length, digit=True, letter=True):
    charrange=''
    if digit: charrange += string.digits
    if letter: charrange += string.ascii_letters
    assert digit or letter
    return ''.join(random.choice(charrange) for _ in range(length))

def cut_out(a,b,string, greedy=False, crossline=False):
    import re
    backslash = "\\"
    result = re.findall(f".*{a}({'.' if not crossline else f'[{backslash}s{backslash}S]'}*{'' if greedy else '?'}){b}.*",string)
    return result

def getTimeStr(format="%Y%m%d_%H%M%S"):
    now = datetime.datetime.now().strftime(format)
    return now

class txtRecord(object):
    def __init__(
        self,
        workDir='.'
        ):
        self.workDir=Path(workDir)
        self.workDir.mkdir(parents=True,exist_ok=True)
        self.file=None
        self.buffer=[]
    
    def reset(self, name='record'):
        name=name[:20]
        filename=f"{name}_{getTimeStr()}.txt"
        if self.file is not None:
            self.file.close()
        filePath=uniqueSecureFilename(self.workDir / filename)
        self.file=open(filePath, 'w', buffering=1)
        self.buffer=[]
    
    def record(self, *kargs, **kwargs):
        itemList=[]
        if len(kargs) > 0:
            itemList=kargs
        elif len(self.buffer) > 0:
            itemList=self.buffer
            self.buffer=[]
        if len(itemList) > 0:
            text=''
            for item in itemList:
                text=text+str(item)
            self.file.write(text)
            self.file.write('\n')
        
    def push(self, *kargs, **kwargs):
        for item in kargs:
            self.buffer.append(item)

    def __del__(self):
        self.record()
        if self.file is not None:
            self.file.close()

