# Copyright 2014 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Manage Google Low Overhead Authentication Service (LOAS) tasks.

This is used by scripts that run outside the chroot and require access to
Google production resources.

If you don't know what any of this means, then you don't need this module :).
"""

import datetime
import logging
import socket
import subprocess

from chromite.lib import alerts
from chromite.lib import cros_build_lib


class LoasError(Exception):
    """Raised when a LOAS error occurs"""


class Loas:
    """Class for holding all the various LOAS cruft."""

    def __init__(self, user, email_notify, email_server=None) -> None:
        """Initialize.

        Args:
            user: The LOAS account to check.
            email_notify: The people to notify when the cert is going to expire.
            email_server: The e-mail server to use when notifying.
        """
        self.user = user
        self.email_notify = email_notify
        self.email_server = email_server
        self.enroll_msg = 'become -t -c "gcert --loas2" %s@%s' % (
            self.user,
            socket.getfqdn(),
        )
        self.last_notification = datetime.date.today() - datetime.timedelta(
            weeks=10
        )

    def Check(self) -> None:
        logging.debug("Checking LOAS credentials for %s", self.user)
        cmd = ["runloas", "/usr/bin/loas_check"]

        # Error message to print when loas credential check fails. This usually
        # is the result of production credentials expiring for accessing
        # Keystore for the unwrapping private key.
        loas_error = "loas_check for %s failed! Did you run: %s" % (
            self.user,
            self.enroll_msg,
        )
        try:
            cros_build_lib.sudo_run(cmd, user=self.user)
        except cros_build_lib.RunCommandError as e:
            raise LoasError("%s\n%s" % (e.msg, loas_error))

    def Status(self) -> None:
        # Only bother checking once a day.  Our certs are valid in the
        # range of weeks, so there's no need to constantly do this.
        if datetime.date.today() < self.last_notification + datetime.timedelta(
            days=1
        ):
            return

        # Let the tool tell us whether things will fail soon.
        cmd = [
            "gcertstatus",
            "--check_loas2",
            "--nocheck_ssh",
            f"--check_remaining={7 * 24}h",
        ]
        result = cros_build_lib.sudo_run(
            cmd,
            user=self.user,
            check=False,
            stdout=True,
            stderr=subprocess.STDOUT,
            encoding="utf-8",
        )

        # Send out one notification a day if there's a week or less left
        # before our creds expire.
        if result.returncode:
            alerts.SendEmail(
                "Loas certs expiring soon!",
                self.email_notify,
                server=self.email_server,
                message="Please run:\n %s\n\n%s\n%s"
                % (self.enroll_msg, result.stdout, result.stderr),
            )
            self.last_notification = datetime.date.today()
        else:
            # We won't expire for a while, so stop the periodic polling.
            self.last_notification = datetime.date.today() + datetime.timedelta(
                days=7
            )
