# Copyright 2022 The Debusine Developers
# See the AUTHORS file at the top-level directory of this distribution
#
# This file is part of Debusine. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution. No part of Debusine, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the LICENSE file.

"""DebusineBaseCommand extends BaseCommand with extra functionality."""
import signal

from django.core.management import BaseCommand
from django.db.utils import DatabaseError


class DebusineBaseCommand(BaseCommand):
    """Extend Django Base Command with functionality used by Debusine."""

    @staticmethod
    def _exit_handler(signum, frame):  # noqa: U100
        """
        Exit without printing Python's default stack trace.

        A user can Control+C and debusine-admin does not print all the
        stack trace. This could happen in any command but is more obvious
        on the interactive commands (such as `remove_tokens` when it asks for
        confirmation)
        """
        raise SystemExit(3)

    def execute(self, *args, **options):
        """
        Catch OperationalError and print a friendly message.

        Possible OperationErrors: database not reachable, invalid database
        credentials, etc.
        """
        try:
            signal.signal(signal.SIGINT, self._exit_handler)
            signal.signal(signal.SIGTERM, self._exit_handler)
            super().execute(*args, **options)
        except DatabaseError as exc:
            self.stderr.write(f"Error connecting to the database: {exc}")
            raise SystemExit(3)
