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

from utils.common import log
from IPy import IP
from utils.client.pecker_client import SSHClient
from utils.common.exception import FCDException
from utils.common.ssh_util import Ssh as SshUtil


class PingSSHclient(SSHClient):

    def linux_command_new(self, cmd, timeout=None):
        '''
        执行结果返回中，增加state返回
        :param cmd:
        :param timeout:
        :return:state, out
        '''
        state = True
        self.thread_lock.acquire()
        stdin, stdout, stderr = self.ssh_client.exec_command(cmd, timeout=timeout)
        self.out = stdout.read()
        self.err = stderr.read()
        if self.err and self.err != "dos2unix: converting file source to Unix format ...\n":
            log.warning(self.err)
            state = False
        log.debug(self.out)
        self.thread_lock.release()
        return state, self.out, self.err


def client_can_pinged_to(client, host, normal=True):
    """
    return the host can pinged to or not
    :param client: PingSSHclient object
    :param host: the host ip of the vm
    :return:
    True ---can be pinged to
    False ---can not be pinged to
    """
    try:
        import traceback
        import platform
        if IP(host).version() == 6:
            ping_act = "ping6"
        else:
            ping_act = "ping"
        if platform.system() == 'Windows':
            cmd = '%s -w 1000 -n %d %s' % (ping_act, 3, host)
        else:
            cmd = '%s -W 1 -c %d %s' % (ping_act, 3, host)
        try:
            if normal:
                ping_times = 3
            else:
                ping_times = 10
            res = loop_ping_cmd(ping_times, client, cmd, host, platform)
            if res:
                return True
            return False
        except Exception as e:
            log.error('try ping host:%s failed:%s' % (host, str(e)))
            log.error(traceback.format_exc())
    except Exception as err:
        log.error('ping to host:%s failed. maybe host cannot be reached. the error is:%s' % (host, str(err)))
        return False


def loop_ping_cmd(ping_times, client, cmd, host, platform):
    for i in range(0, ping_times):
        state, out, err = client.linux_command_new(cmd)
        log.debug('localhost: %s,ping host:%s, std_output:%s, err_output:%s' % (client.host, host, out, err))
        if platform.system() == 'Windows':
            if str(out).find('TTL=') >= 0:
                return True
            else:
                continue
        else:
            if str(out).find('ttl=') >= 0:
                return True
            else:
                continue


class ExecCmd():

    def check_switch_root(self, client, root_pwd):
        try:
            SshUtil.ssh_send_command(client, "su - root", "Password:", timeout=30)
            SshUtil.ssh_send_command(client, root_pwd, "#", timeout=30)
            return True
        except FCDException as e:
            log.error("[FSBR] Switch root fail. Not get expected output,detail: %s" % str(e))
            return False

    def check_language(self, client):
        try:
            pattern = re.compile("zh_CN")
            cmd = "echo $LANG"
            resp = SshUtil.ssh_exec_command_return(client, cmd, retry_times=3)
            result = ''.join(resp)
            log.info("[FSBR] exec command success. detail:%s" % result)
            if pattern.findall(result):
                return False
            return True
        except FCDException as e:
            log.error("[FSBR] Check language fail.detail: %s" % str(e))
            return False

    def create_client(self, host_ip, username, passwd):
        return SshUtil.ssh_create_client(host_ip, username, passwd)

    def close_client(self, client):
        SshUtil.ssh_close(client)
