from abstract_utilities import read_from_file,eatAll,inspect, os
import_tag = 'import '
from_tag = 'from '
def get_caller_path(i=None):
    i = i or 1
    frame = inspect.stack()[i]
    return os.path.abspath(frame.filename)
def make_list(obj:any) -> list:
    """
    Converts the input object to a list. If the object is already a list, it is returned as is.
    
    Args:
        obj: The object to convert.
        
    Returns:
        list: The object as a list.
    """
    if isinstance(obj,str):
        if ',' in obj:
            obj = obj.split(',')
    if isinstance(obj,set) or isinstance(obj,tuple):
        return list(obj)
    if isinstance(obj, list):
        return obj
    return [obj]
def getAlphas(lower=True,capitalize=False,listObj=False):
    obj = ''
    alphas = 'abcdefghijklmoprstuvwxyz'
    if lower:
        obj+=alphas
    if capitalize:
        obj+=alphas.upper()
    if listObj:
        obj = list(obj)
    return obj
def getInts(string=False,listObj=False):
    obj=12345678909
    if string:
        obj = str(obj)
    if listObj:
        obj = list(obj)
    return obj
def get_alpha_ints(ints=True,alpha=True,lower=True,capitalize=True,string=True,listObj=True):
    objs = [] if listObj else ""
    if ints:
        objs+=getInts(string=string,listObj=listObj)
    if alpha:
        objs+=getAlphas(lower=lower,capitalize=capitalize,listObj=listObj)
    return objs
def eatElse(
    stringObj,
    chars=None,
    ints=True,
    alpha=True,
    lower=True,
    capitalize=True,
    string=True,
    listObj=True
):
    alpha_ints = get_alpha_ints(
        ints=True,
        alpha=True,
        lower=True,
        capitalize=True,
        string=True,
        listObj=True
        )
    chars = make_list(chars or [])+alpha_ints

    while True:
        if stringObj:
            str_0 = stringObj[0] not in chars
            str_1 = stringObj[-1] not in chars
            str_eat = str_0 or str_1
            if not str_eat:
                return stringObj
            if stringObj and str_0:
                stringObj = stringObj[1:] if len(stringObj) !=1 else ""
            if stringObj and str_1:
                stringObj = stringObj[:-1] if len(stringObj) !=1 else ""   
        else:
            return stringObj
def clean_line(line):
    return eatAll(line,[' ','','\t','\n'])
def is_line_import(line):
    if line and (line.startswith(from_tag) or line.startswith(import_tag)):
        return True
    return False
def is_line_group_import(line):
    if line and (line.startswith(from_tag) and import_tag in line):
        return True
    return False
def get_import_pkg(line):
    if is_line_group_import(line):
    
        return clean_line(line.split(from_tag)[1].split(import_tag)[0])
def get_imports_from_import_pkg(line):
    if is_line_group_import(line):
        return get_cleaned_import_list(line,commaClean=True)
##def is_local_or_import(pkg_name,file_path):
##    dirname = os.path.dirname(file_path)
##    parts = part for part in dirname.split('/') if part]
##    i=0
##    pkg = pkg_name
##    while True:
##        if pkg and pkg.startswith('.'):
##            i +=1
##            pkg=pkg[1:] if len(pkg)>1 else ""
##        else:
##            if i > 1 and len(parts)>=i:
##                pkg = '.'.join(parts[:-i])
##                .{pkg}"
##        parts
    
    
def add_imports_to_import_pkg_js(import_pkg,imports,import_pkg_js=None):
    import_pkg_js = import_pkg_js or {}
    imports = clean_imports(imports)
    if import_pkg not in import_pkg_js:
        i = len(import_pkg_js["nulines"])
        import_pkg_js[import_pkg]={"imports":imports,"line":i}
        import_line = f"from {import_pkg} import "
        if import_pkg == "import":
            import_line = import_tag
        import_pkg_js["nulines"].append(import_line)
    else:
        import_pkg_js[import_pkg]["imports"]+=imports
    return import_pkg_js
def update_import_pkg_js(line,import_pkg_js=None):
    import_pkg_js = import_pkg_js or {}
    if is_line_group_import(line):
        import_pkg = get_import_pkg(line)
        imports = get_imports_from_import_pkg(line)
        import_pkg_js = add_imports_to_import_pkg_js(import_pkg,imports,import_pkg_js=import_pkg_js)
    else:
        if len(import_pkg_js["nulines"]) >0 and line == '' and is_line_import(import_pkg_js["nulines"][-1]):
            pass
        else:
            import_pkg_js["nulines"].append(line)
    return import_pkg_js
def is_from_line_group(line):
    if line and line.startswith(from_tag) and import_tag in line and '(' in line:
        import_spl = line.split(import_tag)[-1]
        import_spl_clean = clean_line(line)
        if not import_spl_clean.endswith(')'):
            return True
    return False
def clean_imports(imports,commaClean=True):
    chars=["*"]
    if not commaClean:
        chars.append(',')
    if isinstance(imports,str):
        imports = imports.split(',')
    return [eatElse(imp,chars=chars) for imp in imports if imp]
def get_cleaned_import_list(line,commaClean=True):
    cleaned_import_list=[]
    if import_tag in line:
        imports = line.split(import_tag)[1]
        cleaned_import_list+=clean_imports(imports,commaClean=commaClean)
    return cleaned_import_list
def clean_imports(text=None,file_path=None,write=False):
    text = text or ''
    imports_js = {}
    if file_path and os.path.isfile(file_path):
        text+=read_from_file(file_path)
    lines = text.split('\n')
    cleaned_import_list=[]
    nu_lines = []
    j=None
    is_from_group = False
    import_pkg_js={"nulines":[],"file_path":file_path}
    for line in lines:
        if line.startswith(import_tag) and ' from ' not in line:
            cleaned_import_list = get_cleaned_import_list(line)
            import_pkg_js = add_imports_to_import_pkg_js("import",cleaned_import_list,import_pkg_js=import_pkg_js)
        else:
            if is_from_group:
                import_pkg=is_from_group
                line = clean_line(line)
                if line.endswith(')'):
                   is_from_group=False
                   line=line[:-1]
                imports_from_import_pkg = clean_imports(line)
                import_pkg_js = add_imports_to_import_pkg_js(import_pkg,imports_from_import_pkg,import_pkg_js=import_pkg_js)
                
            else:
                import_pkg_js=update_import_pkg_js(line,import_pkg_js=import_pkg_js)
            if is_from_line_group(line) and is_from_group == False:
                
                is_from_group=get_import_pkg(line)
    nu_lines = import_pkg_js["nulines"]
    for pkg,values in import_pkg_js.items():
        comments = []
        if pkg not in ["nulines","file_path"]: 
            line = values.get('line')
            imports = values.get('imports')
            for i,imp in enumerate(imports):
                if '#' in imp:
                    imp_spl = imp.split('#')
                    comments.append(imp_spl[-1])
                    imports[i] = clean_line(imp_spl[0])
            imports = list(set(imports))   
            if '*' in imports:
                imports="*"
            else:
                imports=','.join(imports)
                if comments:
                    comments=','.join(comments)
                    imports+=f" #{comments}"
                    
            nu_lines[line] += imports
    contents = '\n'.join(nu_lines)
    if file_path and write:
        write_to_file(contents=contents,file_path=file_path)
    return contents
