#!/usr/bin/env python

__author__ = 'Carl M. Kobel'


"""
This is the launcher script for assemblycomparator2.

It has two functions.
1) It checks that the necessary environment variables has been set. If not, it uses reasonable defaults.
2) Then it calls the snakemake pipeline using the command line arguments passed to this here script.

Because any command line arguments are passed directly to the subprocess.run()-snakemake call in the bottom of this script, you can use any snakemake-compatible command line argument to this script. E.g: `asscom2 --dry-run`.

This "binary" file works instead of the alias that has been previously used.

"""


import logging
import os 
import sys
import subprocess
import shutil

# Create logger that prints to the terminal.
logger = logging.getLogger('asscom2_launcher')
logger.setLevel(logging.INFO)
console_handler = logging.StreamHandler()
#console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)





# Read system variables and use defaults if necessary.

# Sets the ASSCOM2_BASE to the directory of this python script file which (script file) should be neighboring the correct snakefile.
try:
    ASSCOM2_BASE = os.environ['ASSCOM2_BASE']
    logger.debug(f"ASSCOM2_BASE was already set to \"{ASSCOM2_BASE}\".")
except KeyError as e:
    ASSCOM2_BASE = os.path.dirname(os.path.realpath(__file__)) # This seems to work even for symlinks (it gets the physical path.)
    os.environ["ASSCOM2_BASE"] = ASSCOM2_BASE
    logger.debug(f"ASSCOM2_BASE was not set and has been defaulted to \"{ASSCOM2_BASE}\".")

# Defines the ASSCOM2_PROFILE relative to the ASSCOM2_BASE if not set already.
# Detects and prioritizes to use apptainer if it exists.
try:
    ASSCOM2_PROFILE = os.environ['ASSCOM2_PROFILE']
    logger.debug(f"ASSCOM2_PROFILE was already set to \"{ASSCOM2_PROFILE}\".")
except KeyError as e: # The profile has not been set.
    # We might check whether apptainer is present. If it is we will use it, if not, we'll use conda.
    if shutil.which("apptainer") is not None: # Apptainer exists, use it.
        ASSCOM2_PROFILE = f"{ASSCOM2_BASE}/profiles/apptainer/local"
        logger.debug(f"Using apptainer.")
    else: 
        ASSCOM2_PROFILE = f"{ASSCOM2_BASE}/profiles/conda/local"
        logger.debug(f"Using conda.")
    
    os.environ["ASSCOM2_PROFILE"] = ASSCOM2_PROFILE
    logger.debug(f"ASSCOM2_PROFILE was not set and has been defaulted to \"{ASSCOM2_PROFILE}\".")

# Defines the ASSCOM2_DATABASES relative to the ASSCOM2_BASE if not set already.
try:
    ASSCOM2_DATABASES = os.environ['ASSCOM2_DATABASES']
    logger.debug(f"ASSCOM2_DATABASES was already set to \"{ASSCOM2_DATABASES}\".")
except KeyError as e:
    ASSCOM2_DATABASES = f"{ASSCOM2_BASE}/databases"
    os.environ["ASSCOM2_DATABASES"] = ASSCOM2_DATABASES
    logger.debug(f"ASSCOM2_DATABASES was not set and has been defaulted to \"{ASSCOM2_DATABASES}\".")






# Then call the pipeline (alias) using the variables that have just been set, including the command line parameters that have been passed to this script. As we have already saved the new environment variables with os.environ(), we can just call as is.

# I will have to check whether this will work for both conda and apptainer based installations? It should. In the test on bioconda I should use conda (not apptainer).

# Concatenate the trailing command line arguments to add to the snakemake command.
trailing_arguments = " ".join(sys.argv[1:])
logger.debug(f"The concatenated trailing arguments are {trailing_arguments}")

command = f"snakemake --snakefile {ASSCOM2_BASE}/snakefile --profile {ASSCOM2_PROFILE} --configfile {ASSCOM2_BASE}/config.yaml  " + trailing_arguments
logger.debug(f"Command to run is\n{command}")

# Finally, run the pipeline.
subprocess.run(command, shell = True)

