#!/usr/bin/python3

"""
Run several simtools applications using a configuration file.

Allows to run several simtools applications with a single configuration file, which includes
both the name of the simtools application and the configuration for the application.

This application is used for model parameter setting workflows.
Strong assumptions are applied on the directory structure for input and output files of
applications, for details see the CTAO Simulation Model Parameter Setting
`repository <https://gitlab.cta-observatory.org/cta-science/simulations/simulation-model/\
simulation-model-parameter-setting>`_.

.. tip::
   Browse the CTAO Simulation Model Parameter Setting
   `repository <https://gitlab.cta-observatory.org/cta-science/simulations/simulation-model/\
simulation-model-parameter-setting>`_
   for a list of examples and templates for configuration files.

For simplified configuration, a placeholder called ``__SETTING_WORKFLOW__`` can be used in the
configuration file. This placeholder will be replaced with the directory below ``input``
(example: configuration file is in ``input/LSTN-design/num_gains/20250214T134800/config.yml``,
then the placeholder will be replaced with ``LSTN-design/num_gains/20250214T134800``).
This will also be the directory for any output generated by the application.

Run time environments can be defined in the configuration file using the ``runtime_environment``
block. The following example shows how to define a runtime environment:

.. code-block:: yaml

     runtime_environment:
     image: ghcr.io/gammasim/simtools-prod-sim-telarray-240927-corsika-77550-bernlohr-1.68-\
prod6-baseline-qgs2-no_opt:20250716-122341
     network: simtools-mongo-network
     environment_file: ./.env
     container_engine: podman
     options:
     - '--arch amd64'

If the ``ignore_runtime_environment`` flag is set, the application will run in the current
environment, ignoring any definitions in the configuration file.

The database configuration and setting of other environment variables is done as
described in :ref:`environment-variables`.

Example
-------

Run the application with the configuration file ``config_file_name``:

.. code-block:: console

     simtools-run-application --configuration_file config_file_name

Run the application with the configuration file ``config_file_name``, but skipping all steps except
step 2 and 3 (useful for debugging):

.. code-block:: console

     simtools-run-application --configuration_file config_file_name --steps 2 3

"""

from simtools.application_control import get_application_label, startup_application
from simtools.configuration import configurator
from simtools.runners import simtools_runner


def _parse():
    """Parse command line configuration."""
    config = configurator.Configurator(
        label=get_application_label(__file__),
        description="Run simtools applications using a configuration file.",
        usage="simtools-run-application --config_file config_file_name",
    )

    config.parser.add_argument(
        "--configuration_file",
        help="Application configuration.",
        type=str,
        required=True,
        default=None,
    )
    config.parser.add_argument(
        "--steps",
        type=int,
        nargs="+",
        help="List of steps to be execution (e.g., '--steps 7 8 9'; do not specify to run all).",
    )
    config.parser.add_argument(
        "--ignore_runtime_environment",
        action="store_true",
        help="Ignore the runtime environment and run the application in the current environment.",
        default=False,
    )
    return config.initialize(db_config=True)


def main():
    """Run several simtools applications using a configuration file."""
    app_context = startup_application(_parse, setup_io_handler=False)

    simtools_runner.run_applications(app_context.args, app_context.db_config, app_context.logger)


if __name__ == "__main__":
    main()
