#!/usr/bin/env python3

"""
Copyright 2020 The Magma Authors.

This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree.

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import asyncio
import os
import subprocess
from datetime import datetime

import apt
from dateutil import tz
from common.health.entities import (
    ActiveState,
    Errors,
    HealthStatus,
    HealthSummary,
    RestartFrequency,
    ServiceHealth,
    Version,
)
from common.service import MagmaService
from common.service_registry import ServiceRegistry
from configuration.mconfig_managers import load_service_mconfig_as_json
from magmad.metrics import UNEXPECTED_SERVICE_RESTARTS
from magmad.service_poller import ServicePoller
from orc8r.protos import common_pb2, magmad_pb2
from orc8r.protos.magmad_pb2_grpc import MagmadStub
from orc8r.protos.mconfig import mconfigs_pb2
from pystemd.systemd1 import Unit


class GenericHealthChecker:

    def ping(self, host, num_packets=4):
        chan = ServiceRegistry.get_rpc_channel('magmad', ServiceRegistry.LOCAL)
        client = MagmadStub(chan)

        response = client.RunNetworkTests(
            magmad_pb2.NetworkTestRequest(
                pings=[
                    magmad_pb2.PingParams(
                        host_or_ip=host,
                        num_packets=num_packets,
                    ),
                ],
            ),
        )
        return response.pings

    def ping_status(self, host):
        pings = self.ping(host=host, num_packets=4)[0]
        if pings.error:
            return HealthStatus.DOWN
        if pings.avg_response_ms:
            return HealthStatus.UP
        return HealthStatus.UNKNOWN

    def get_error_summary(self, service_names):
        """Get the list of services with the error count.

        Args:
            service_names: List of service names.

        Returns:
            A dictionary with service name as a key and the Errors object
            as a value.

        Raises:
            PermissionError: User has no permision to exectue the command
        """
        configs = {
            service_name: load_service_mconfig_as_json(service_name)
            for service_name in service_names
        }
        res = {
            service_name: Errors(
            log_level=configs[service_name].get('logLevel', 'INFO'),
            error_count=0,
            )
            for service_name in service_names
        }

        syslog_path = '/var/log/syslog'
        if not os.access(syslog_path, os.R_OK):
            raise PermissionError(
                'syslog is not readable. '
                'Try `sudo chmod a+r {}`. '
                'Or execute the command with sudo '
                'permissions: `venvsudo`'.format(syslog_path),
            )
        with open(syslog_path, 'r', encoding='utf-8') as f:
            for line in f:
                for service_name in service_names:
                    if service_name not in line:
                        continue
                    # Reset the counter for restart/start
                    if 'Starting {}...'.format(service_name) in line:
                        res[service_name].error_count = 0
                    elif 'ERROR' in line:
                        res[service_name].error_count += 1
        return res

    def get_magma_services_summary(self):
        """ Get health for all the running services """
        services_health_summary = []

        # DBus objects: https://www.freedesktop.org/wiki/Software/systemd/dbus/
        chan = ServiceRegistry.get_rpc_channel('magmad', ServiceRegistry.LOCAL)
        client = MagmadStub(chan)

        configs = client.GetConfigs(common_pb2.Void())

        service_names = [str(name) for name in configs.configs_by_key]
        services_errors = self.get_error_summary(service_names=service_names)

        for service_name in service_names:
            unit = Unit(
                'magma@{}.service'.format(service_name),
                _autoload=True,
            )
            active_state = ActiveState.dbus2state[unit.Unit.ActiveState]
            sub_state = str(unit.Unit.SubState, 'utf-8')
            if active_state == ActiveState.ACTIVE:
                pid = unit.Service.MainPID
                process = subprocess.Popen(
                    'ps -o etime= -p {}'.format(pid).split(),
                    stdout=subprocess.PIPE,
                )

                time_running, error = process.communicate()
                if error:
                    raise ValueError(
                        'Cannot get time running for the service '
                        '{} `ps -o etime= -p {}`'
                        .format(service_name, pid),
                    )
            else:
                time_running = b'00'

            services_health_summary.append(
                ServiceHealth(
                    service_name=service_name,
                    active_state=active_state, sub_state=sub_state,
                    time_running=str(time_running, 'utf-8').strip(),
                    errors=services_errors[service_name],
                ),
            )
        return services_health_summary

    def get_unexpected_restart_summary(self):
        service = MagmaService('magmad', mconfigs_pb2.MagmaD())
        service_poller = ServicePoller(service.loop, service.config)
        service_poller.start()

        asyncio.set_event_loop(service.loop)

        # noinspection PyProtectedMember
        # pylint: disable=protected-access
        async def fetch_info():
            restart_frequencies = {}
            await service_poller._get_service_info()
            for service_name in service_poller.service_info.keys():
                restarts = int(
                    UNEXPECTED_SERVICE_RESTARTS
                    .labels(service_name=service_name)
                    ._value.get(),
                )
                restart_frequencies[service_name] = RestartFrequency(
                    count=restarts,
                    time_interval='',
                )

            return restart_frequencies

        return service.loop.run_until_complete(fetch_info())

    def get_kernel_version(self):
        info, error = subprocess.Popen(
            'uname -a'.split(),
            stdout=subprocess.PIPE,
        ).communicate()

        if error:
            raise ValueError('Cannot get the kernel version')
        return str(info, 'utf-8')

    def get_magma_version(self):
        cache = apt.Cache()

        # Return the python version if magma is not there
        if 'magma' not in cache:
            return Version(
                version_code=cache['python3'].versions[0],
                last_update_time='-',
            )

        pkg = str(cache['magma'].versions[0])
        version = pkg.split('-')[0].split('=')[-1]
        timestamp = int(pkg.split('-')[1])

        return Version(
            version_code=version,
            last_update_time=datetime.utcfromtimestamp(timestamp)
            .replace(tzinfo=tz.tzutc())
            .astimezone(tz=tz.tzlocal())
            .strftime('%Y-%m-%d %H:%M:%S'),
        )

    def get_health_summary(self):

        return HealthSummary(
            version=self.get_magma_version(),
            platform=self.get_kernel_version(),
            services_health=self.get_magma_services_summary(),
            internet_health=self.ping_status(host='8.8.8.8'),
            dns_health=self.ping_status(host='google.com'),
            unexpected_restarts=self.get_unexpected_restart_summary(),
        )
