import tempfile

from biolib import utils
from biolib.biolib_binary_format import UnencryptedModuleOutput, InMemoryIndexableBuffer
from biolib.biolib_errors import BioLibError
from biolib.biolib_logging import logger
from biolib.compute_node.job_worker.executors import RemoteExecutor, RemoteExecuteOptions
from biolib.compute_node.job_worker.job_worker import JobWorker
from biolib.typing_utils import Optional


def run_job(
        job,
        module_input_serialized: bytes,
        force_local: bool = False,
        result_name_prefix: Optional[str] = None,
) -> UnencryptedModuleOutput:
    job_id = job['public_id']
    logger.info(f'Job "{job_id}" is starting...')

    if not force_local:
        return RemoteExecutor.execute_job(
            RemoteExecuteOptions(
                biolib_base_url=utils.BIOLIB_BASE_URL,
                job=job,
                result_name_prefix=result_name_prefix,
                root_job_id=job_id,
            ),
            module_input_serialized,
        )

    if not job['app_version'].get('modules'):
        BioLibError('Unable to run the application locally')

    with tempfile.TemporaryDirectory() as job_temporary_dir:
        module_output_path = JobWorker().run_job_locally(job, module_input_serialized, job_temporary_dir)

        with open(module_output_path, mode='rb') as module_output_file:
            module_output_serialized = module_output_file.read()

        return UnencryptedModuleOutput(InMemoryIndexableBuffer(module_output_serialized))
