#!/usr/bin/python
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Utility to check the replication delay of the slave databases.

The utility checks the value of Seconds_Behind_Master of slave databases,
including:
Slave databases of AFE database, retrieved from server database.
Readonly replicas of TKO database, passed in by option --replicas.
"""

import argparse
import logging
import os
import re

import common
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib import logging_config
from autotest_lib.frontend import setup_django_environment
from autotest_lib.server import site_utils
from autotest_lib.site_utils import server_manager_utils

from chromite.lib import metrics


CONFIG = global_config.global_config

# SQL command to remove old test results in TKO database.
SLAVE_STATUS_CMD = 'show slave status\G'
DELAY_TIME_REGEX = 'Seconds_Behind_Master:\s(\d+)'
DELAY_METRICS = 'chromeos/autotest/afe_db/seconds_behind_master'
# A large delay to report to metrics indicating the replica is in error.
LARGE_DELAY = 1000000

def check_delay(server, user, password):
    """Check the delay of a given slave database server.

    @param server: Hostname or IP address of the MySQL server.
    @param user: User name to log in the MySQL server.
    @param password: Password to log in the MySQL server.
    """
    try:
        result = utils.run_sql_cmd(server, user, password, SLAVE_STATUS_CMD)
        search = re.search(DELAY_TIME_REGEX, result, re.MULTILINE)
        if search:
            delay = int(search.group(1))
            metrics.SecondsDistribution(DELAY_METRICS).add(
                    delay, fields={'server': server})
            logging.debug('Seconds_Behind_Master of server %s is %d.', server,
                          delay)
        else:
            # The value of Seconds_Behind_Master could be NULL, report a large
            # number to indicate database error.
            metrics.SecondsDistribution(DELAY_METRICS).add(
                    LARGE_DELAY, fields={'server': server})
            logging.error('Failed to get Seconds_Behind_Master of server %s '
                          'from slave status:\n %s', server, result)
    except error.CmdError:
        logging.exception('Failed to get slave status of server %s.', server)


def parse_options():
    """Parse command line inputs.

    @return: Options to run the script.
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('-r', '--replicas', nargs='+',
                        default=[],
                        help='IP addresses of readonly replicas of TKO.')
    parser.add_argument('-l', '--logfile', type=str,
                        default=None,
                        help='Path to the log file to save logs.')
    return parser.parse_args()


def main():
    """Main script."""
    with site_utils.SetupTsMonGlobalState('check_slave_db_delay',
                                          short_lived=True):
        options = parse_options()
        log_config = logging_config.LoggingConfig()
        if options.logfile:
            log_config.add_file_handler(
                file_path=os.path.abspath(options.logfile),
                level=logging.DEBUG
            )
        db_user = CONFIG.get_config_value('AUTOTEST_WEB', 'user')
        db_password = CONFIG.get_config_value('AUTOTEST_WEB', 'password')

        global_db_user = CONFIG.get_config_value(
                    'AUTOTEST_WEB', 'global_db_user', default=db_user)
        global_db_password = CONFIG.get_config_value(
                    'AUTOTEST_WEB', 'global_db_password', default=db_password)

        logging.info('Start checking Seconds_Behind_Master of slave databases')

        if not options.replicas:
            logging.warning('No replicas checked.')
        else:
            for replica in options.replicas:
                check_delay(replica, global_db_user, global_db_password)

        slaves = server_manager_utils.get_servers(
                role='database_slave', status='primary')
        for slave in slaves:
            check_delay(slave.hostname, db_user, db_password)

        logging.info('Finished checking.')


if __name__ == '__main__':
    main()
