import glob, os
import subprocess

class WfSmith:
    def __init__(self, paths):
        self.paths = paths
        self.virtualizations = {}

    def load_available_virtualizations(self):
        for path in self.paths: self.load_virtualizations(path)

    def load_virtualizations(self, path):
        #.autoflow_smith
        #|.. virtualization
        #   |.. env
        #     |..env1
        #     |..env2
        #   |.. sing 
        #     |..sing1
        #     |..sing2
        base_path = os.path.join(path, '.autoflow_smith')
        env_virt = {} #python env
        self.virtualizations['env'] = env_virt
        for p in glob.glob(os.path.join(base_path, 'env', '*')): env_virt[os.path.basename(p)] = p
        sing_virt = {} #singularity images
        self.virtualizations['sing'] = sing_virt
        for p in glob.glob(os.path.join(base_path, 'sing', '*')): sing_virt[os.path.basename(p)] = p


    def create_virtualization(self, virt_type, path, name, options):
        # virt_type: env, sing
        base_path = os.path.join(path, '.autoflow_smith', virt_type, name)
        os.makedirs(base_path)
        if virt_type == 'env':
            venv_opts = ''
            if options['venv_opts'] != None: venv_opts = ' '.join(options['venv_opts'])
            cmd = f"python -m venv {venv_opts} {name} {base_path} "
            result = subprocess.check_output(cmd, shell = True).decode("utf-8")
            print(result)
            with open(os.path.join(base_path, 'requirements.txt'), 'w') as f: 
                f.write('\n'.join(options['requirements']))
            pip_opts = ''
            if options['pip_opts'] != None: pip_opts = ' '.join(options['pip_opts'])
            cmd = f"source {os.path.join(base_path, 'bin', 'activate')}; pip install {pip_opts} -r {os.path.join(base_path, 'requirements.txt')}"
            result = subprocess.check_output(cmd, shell = True).decode("utf-8")
            print(result)
        self.regist_virt(virt_type, name, base_path)

    def regist_virt(self, virt_type, name, path):
        virt = self.virtualizations.get(virt_type)
        if virt == None:
            virt = {}
            self.virtualizations[virt_type] = virt
        virt[name] = path

    def exists_virt(self, virt_type, name):
        exists = False
        virt = self.virtualizations.get(virt_type)
        if virt != None:
            path = virt.get(name)
            if path != None: exists = True
        return exists

    def configure_virt_from_resource_profiles(self, profiles, path):
        for name,  profile in profiles.items():
            if not self.exists_virt(profile['virt_type'], name): 
                self.create_virtualization(profile['virt_type'], path, name, profile)

    def get_virt_init_command(self, virt_type, name):
        command = None
        virt = self.virtualizations.get(virt_type)
        path = virt.get(name)
        if path != None:
            if virt_type == 'env':
                command = f"source {os.path.join(path, 'bin', 'activate')}"
        return command
                
                

