#!/usr/bin/python3

# SPDX-FileCopyrightText: Red Hat, Inc.
# SPDX-License-Identifier: GPL-2.0-or-later

from __future__ import absolute_import

import checkips_utils
import os
import subprocess
import sys
import syslog
import time
import threading

from vdsm import constants
import vdsm.network.netconfpersistence as persist_net

sys.path.append(os.path.join(constants.P_VDSM_HOOKS, 'after_get_stats'))

PING_TIMEOUT = 15
PING_SAMPLE_TIME = 20
CHECKIPV4 = 'checkipv4'
CHECKIPV6 = 'checkipv6'
VDSM_CHECKIPS = 'vdsm-checkips'


def _ping_address(address, address_type, network):
    ping_cmd = 'ping' if address_type == CHECKIPV4 else 'ping6'
    command = [
        ping_cmd,
        '-c', '1',
        '-w', str(PING_TIMEOUT),
        address
    ]
    p = subprocess.Popen(
        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    out, _ = p.communicate()
    if not p.returncode:
        checkips_utils.touch(network, constants.P_VDSM_RUN)
    # Not sure about this, flood the journalctl log
    elif out:
        syslog.syslog(
            "%s: failed to ping address %s: %s" %
            (VDSM_CHECKIPS, address, out)
        )


def _ping_addresses():
    threads = []
    networks = persist_net.PersistentConfig().networks
    for net, net_attrs in networks.items():
        ping_addresses = checkips_utils.get_ping_addresses(net_attrs)
        if ping_addresses:
            for address_type, address in ping_addresses:
                ping_thread = threading.Thread(
                    target=_ping_address,
                    args=(address, address_type, net)
                )
                ping_thread.start()
                threads.append(ping_thread)

    for ping_thread in threads:
        ping_thread.join()


def main():
    try:
        while True:
            time_before_ping = time.time()
            _ping_addresses()
            time.sleep(
                PING_SAMPLE_TIME - (time.time() - time_before_ping)
            )
    except Exception as e:
        syslog.syslog("%s: service failed to start: %s" % (VDSM_CHECKIPS, e))
        return 1


if __name__ == '__main__':
    sys.exit(main())
