#!/usr/bin/env python
# -*- coding: utf-8 -*-

from common.util.clients import CacheClient
from django.core.management.base import BaseCommand
from django.db import connections
import socket
import sys
import tankapi.client.client as tankapi
from api.views.tanks_map import get_tanks
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class Command(BaseCommand):
    MAX_CPU = 30
    DISK_WARN = 70
    DISK_ERR = 90
    help = "Collect tank status info and put it into old-style file"

    def handle(self, *args, **options):
        try:
            self.get_all_statuses()
        except Exception as exc:
            sys.stderr.write("Failed get tanks statuses: {}\n".format(exc.__repr__()))

    def get_all_statuses(self):
        res = ""
        all_json = {}
        for tank in get_tanks(''):
            if tank[0].endswith('tanks'):
                host = tank[0] + '.yandex.net'
            elif tank[0].endswith(':30169'):
                host = tank[0].rstrip(':30169')
            else:
                host = tank[0]
            port = 30169 if tank[1] == 'rtc' else 8083
            try:
                data = self.get_tank_status(host, port=port)
            except Exception as e:
                data = {
                    'name': host.split('.')[0].replace('-all-rcloud-tanks-30169', ''),
                    'color': 'grey',
                    'dc': '',
                    'font': '#9e9e9e',
                    'level': 0,
                    'msg': e.__repr__()
                }

            all_json[host.replace('-all-rcloud-tanks-30169', '')] = data
            try:
                if data:
                    res += self.format_record(data)
            except Exception as e:
                sys.stderr.write('Failed to format tank status for {}:\n Data: {}\n {}\n'.format(host, data, repr(e)))

        cache = CacheClient()
        json_result = cache.set('tanks_status_json', all_json)
        if not json_result:
            sys.stderr.write('Failed to put json value to cache\n')
        html_result = cache.set('tanks_status_html', res)
        if not html_result:
            sys.stderr.write('Failed to put html value to cache\n')

    def get_tank_status(self, host, port=8083):
        api = tankapi.LunaparkTank(host, port)
        api.timeout = 10
        socket.setdefaulttimeout(10)
        res = api.get_status()

        color = 'green'
        dc = 'N/A'
        level = 0
        message = ''

        # active people?
        if res.get('users_activity'):
            for user in res['users_activity']:
                for name, idle in user.items():
                    # TODO: calculate idle time and use it
                    color = 'yellow'
                    message += "<b>{}</b> {} idle<br>".format(name, idle)

        # DISK problems?
        if res.get('fs_use') and isinstance(res['fs_use'], dict):
            for fs, fs_use in res['fs_use'].items():
                if int(fs_use['use_p'][:-1]) > self.DISK_ERR:
                    color = 'red'
                    message += "<b>{}</b> (Usage: {})<br>".format(fs, fs_use['use_p'])
                elif int(fs_use['use_p'][:-1]) > self.DISK_WARN:
                    color = 'yellow'
                    message += "<b>{}</b> (Usage: {})<br>".format(fs, fs_use['use_p'])

        # CPU problems?
        if res['processes'] is not None:
            for proc in res['processes']:
                if proc['cpu'] > self.MAX_CPU:
                    color = 'red'
                    message += "<b>{}</b> ({} {}% CPU)<br>".format(proc['command'], proc['user'], proc['cpu'])


        # online test?
        if res['is_testing']:
            color = 'red'
            for jobno in res['lunapark_ids']:
                if jobno is not None:
                    try:
                        assert str(jobno).isdigit()
                        cursor = connections['default'].cursor()
                        cursor.execute("SELECT person from job where n=%(job)s", {'job': jobno})
                        owner = cursor.fetchone()[0]
                        message += "<span class='style6'><b>Cтрельба:</b> <a href='/{}'>{}</a>".format(jobno, jobno)
                        if owner:
                            message += " ({}) ".format(owner)
                        message += "</span><br>"
                    except AssertionError:
                        sys.stderr.write('Invalid jobno {}\n'.format(jobno))
                    except Exception as exc:
                        sys.stderr.write("Problem getting info for job {}: {}\n".format(jobno, exc.__repr__()))

        font_color = ''  # FIXME убрать из фронта

        return {
            'name': res['name'].split('.')[0].replace('-all-rcloud-tanks-30169', ''),
            'color': color,
            'dc': dc,
            'font': font_color,
            'level': level,
            'msg': str(message)
        }

    def format_record(self, data):
        # name, color, descr, font_colr, level, message
        tpl = '<tank>\n ' \
              '<name>{name}</name>\n ' \
              '<color>{color}</color>\n ' \
              '<dc>{dc}</dc>\n ' \
              '<font>{font}</font>\n ' \
              '<level>{level}</level>\n ' \
              '<msg>{msg}</msg>\n' \
              '</tank>\n'
        return tpl.format(**data)
