from subprocess import check_output as co
import os
import numpy as np

def sco(s,split=True):
    try:
        res = co(s,shell=True).decode('utf-8')
    except:
        raise
    if( split ):
        return res.split('\n')[:-1]
    else:
        return res
    
def get_local_name(s,ext='.py'):
    u = s if '/' not in s else s.split('/')[-1]
    u = u.replace(ext + 'x', '')
    return u.replace(ext, '')
    
def get_subfolders(path, **kw):
    omissions = kw.get('omissions', [])
    inclusions = kw.get('inclusions', None)
    local = kw.get('local', True)
    ext = kw.get('ext', '.py')
    depth = kw.get('depth', 1)
    omissions = [path + '/%s'%e if '/' not in e else e for e in omissions]
    if( inclusions != None ):
        inclusions = [path + '/%s'%e if '/' not in e else e for e in inclusions]
    try:
        cmd = r'find %s -maxdepth %d -mindepth %d -type d'%(path, depth, depth)
        u = sco(cmd)
        u = [e for e in u \
            if not e.split('/')[-1].startswith('__') \
                and not e.split('/')[-1].startswith('.')
        ]
    except:
        u = []
    if( len(omissions) > 0 or inclusions != None ):
        if( inclusions != None ):
            [omissions.append(e) for e in u if e not in inclusions] 
        u = [e for e in u if e not in omissions] 
    if( local ):
        u = [get_local_name(e, ext) for e in u]
    return u

def get_local_modules(path, **kw):
    local = kw.get('local', True)
    ext = kw.get('ext', '.py')
    res = sco(
        r'find %s -mindepth 1 -maxdepth 1 -type f -name "*%s"'%(path, ext)
    )
    res2 = sco(
        r'find %s -mindepth 1 -maxdepth 1 -type f -name "*%sx"'%(path, ext)
    )
    [res.append(e) for e in res2]
    res = [e for e in res if \
        not(
                e.split('/')[-1].startswith('.') \
                or e.split('/')[-1].startswith('_')
        )
    ]
    if( local ):
        res = [get_local_name(e) for e in res]
    return res

def init_modules(path, **kw):
    root = kw.get('root', False)
    unload = kw.get('unload', False)
    if( root ):
        local_modules = []
    else:
        local_modules = get_local_modules(path, **kw)
    subfolders = get_subfolders(path, **kw)
    [local_modules.append(e) for e in subfolders]
    s = '__all__ = [\n'
    for e in local_modules:
        s += '    "%s",\n'%e
    if( s == "__all__ = [\n" ):
        s += ']\n'
    else:
        s = s[:-2]
        s += '\n]\n'
    if( unload ):
        v = s.translate(str.maketrans("", "", ' \n"')) \
            .split("[")[1] \
            .split("]")[0] \
            .split(",")
        for e in v:
            s += 'from .%s import *\n'%e
#        s += 'from . import *'
    if( True ):
        filename = path + '/__init__.py'
        with open(filename, 'w') as f:
            print('Write to "%s"\n"%s"'%(filename, s)) 
            f.write(s)

    global_subfolders = ['%s/%s'%(path,e) for e in subfolders]
    kw['root'] = False
    kw['inclusions'] = None
    for e in global_subfolders:
        init_modules(e, **kw)

def run_make_files(omissions=[]):
    ref_path = os.getcwd()
    omissions = [ \
        e \
        if e.startswith('/') \
        else '%s/%s'%(ref_path, e) \
        for e in omissions \
    ]
    make_files = sco('find %s -name "Makefile"'%ref_path, True)
    make_dir = np.array([e.replace('/Makefile','') for e in make_files])
    omit = [np.any([ee in e for ee in omissions]) for e in make_dir]
    make_dir = [e for (i,e) in enumerate(make_dir) if not omit[i]]
    for d in make_dir:
        os.chdir(d)
        os.system('rm __init__.py')
        os.system('make clean')
        os.system('make')
    os.chdir(ref_path)    

