from argparse import ArgumentParser, Namespace

from spotml.commands.abstract_config_command import AbstractConfigCommand
from spotml.commands.writers.abstract_output_writrer import AbstractOutputWriter
from spotml.constants.run_status import STOPPED_DUE_TO_ERROR
from spotml.deployment.abstract_ssh_instance_manager import AbstractSshInstanceManager
from spotml.services.run_service import update_run_status


class HandleErroredRunCommand(AbstractConfigCommand):
    name = 'handle-errored-run'
    description = 'Run a custom script from the configuration file inside the container'

    def configure(self, parser: ArgumentParser):
        super().configure(parser)
        parser.add_argument('script_name', metavar='SCRIPT_NAME', type=str, help='Script name')
        parser.add_argument('-u', '--user', type=str, default=None,
                            help='Container username or UID (format: <name|uid>[:<group|gid>])')
        parser.add_argument('-s', '--session-name', type=str, default=None, help='tmux session name')
        parser.add_argument('-l', '--logging', action='store_true', help='Log the script outputs to a file')
        parser.add_argument('-p', '--parameter', metavar='PARAMETER=VALUE', action='append', type=str, default=[],
                            help='Set a value for the script parameter (format: PARAMETER=VALUE). This '
                                 'argument can be used multiple times to set several parameters. Parameters can be '
                                 'used in the script as Mustache variables (for example: {{PARAMETER}}).')
        parser.add_argument('--no-sync', action='store_true', help='Don\'t sync the project before running the script')

        # add the "double-dash" argument to the usage message
        parser.prog = 'spotml run'
        parser.usage = parser.format_usage()[7:-1] + ' [-- args...]\n'
        parser.epilog = 'The double dash (--) separates custom arguments that you can pass to the script ' \
                        'from the spotml arguments.'

    def _run(self, instance_manager: AbstractSshInstanceManager, args: Namespace, output: AbstractOutputWriter):
        if instance_manager.is_running():
            print("Errored instance is still running, stopping it now")
            instance_manager.stop(only_shutdown=False, output=output)
            update_run_status(args.run_id, STOPPED_DUE_TO_ERROR)
            return
        else:
            print("Errored instance is not running, Nothing to do.")
            update_run_status(args.run_id, STOPPED_DUE_TO_ERROR)
