# coding: utf-8
import os, sys, json,time,socket

from base import *
from files_tools import *
from sys_services import *

#获取Web服务器
def GetWebServer():
    webserver = None
    if get_server_status('nginx') >= 0:
        webserver = 'nginx'
    elif get_server_status('apache') >= 0:
        webserver = 'apache'
    else:
        if os.path.exists('data/iis.setup'): webserver = 'iis'

    return webserver


def serviceReload():
    return ServiceReload()

# 重载Web服务配置
def ServiceReload(siteName=None):
    """
    @siteName 网站名称，IIS专用，重启指定IIS网站
    """
    webserver = get_webserver()
    result = ''
    if webserver == 'nginx':
        ser = psutil.win_service_get(webserver)
        if ser: ExecShell('taskkill /pid {} -t -f'.format(ser.pid()))

        isError = checkWebConfig()
        if isError != True:
            if isError.find('0.0.0.0:80') >= 0: os.system("net stop http /y")
        num = 0
        while num < 5:
            if get_server_status(webserver) == 1: break
            os.system('net start nginx')
            time.sleep(0.2)
            num += 1
    elif webserver == 'apache':

        ser = psutil.win_service_get(webserver)
        if ser: ExecShell('taskkill /pid {} -t -f'.format(ser.pid()))
        isError = checkWebConfig()
        if isError != True:
            if isError.find('0.0.0.0:80') >= 0: os.system("net stop http /y")

        ExecShell('taskkill /f /im php-cig.exe')
        num = 0
        while num < 5:
            if get_server_status(webserver) == 1: break
            os.system('net start apache')
            time.sleep(0.2)
            num += 1
    else:
        if siteName:
            appcmd = "C:\\windows\\system32\\inetsrv\\appcmd.exe"
            ExecShell(appcmd + ' stop apppool /apppool.name:"%s"' % (siteName))

            ExecShell(appcmd + ' start apppool /apppool.name:"%s"' % (siteName))
        else:
            result = ExecShell('iisreset')
    return result

def checkWebConfig():
    """
    检查Web服务器配置文件是否有错误
    """
    serverType = get_webserver()
    if os.name == 'nt':
        if serverType == 'nginx':
            shell = "%s && cd %s/nginx && nginx.exe -t" % (os.getenv("BT_SETUP")[0:2], os.getenv("BT_SETUP"))
            result = ExecShell(shell)

            searchStr = 'successful'
        elif serverType == 'apache':
            shell = os.getenv("BT_SETUP") + '/apache/bin/httpd.exe -t'
            result = ExecShell(shell)
            searchStr = 'Syntax OK'
        else:
            return True
    else:
        if serverType == 'nginx':
            shell = "cd {}/nginx && nginx -t".format(get_soft_path())
            result = ExecShell(shell)
            searchStr = 'successful'
        elif serverType == 'apache':
            shell = "cd {}/apache && apachectl -t".format(get_soft_path())
            result = ExecShell(shell)
            searchStr = 'Syntax OK'
        else:
            return True
    if result[1].find(searchStr) == -1 and result[1] != '':
        WriteLog("TYPE_SOFT", 'CONF_CHECK_ERR', (result[1].replace('\\', '/'),))
        return result[1]
    return True

def get_webserver():
    return GetWebServer()

def get_vhost_path():
    path = '{}/vhost'.format(get_panel_path())
    return path
    
def get_logs_path():
    return os.getenv('BT_SETUP') + "/wwwlogs"

def is_apache_nginx():
    web = get_webserver()
    if web in ['nginx','apache']:
        return True
    return False

def check_salt():

    u_list = M('users').where('salt is NULL', ()).field('id,username,password,salt').select()
    if isinstance(u_list, str):
        if u_list.find('no such table: users') != -1:      

            u_list = M('users').where('salt is NULL', ()).field('id,username,password,salt').select()

    for u_info in u_list:
        salt = GetRandomString(12)  # 12位随机
        pdata = {}
        pdata['password'] = md5(md5(u_info['password'] + '_bt.cn') + salt)
        pdata['salt'] = salt
        M('users').where('id=?', (u_info['id'],)).update(pdata)


def password_salt(password, username=None, uid=None):
 
    check_salt()
    if not uid:
        if not username:
            raise Exception('username或uid必需传一项')
        uid = M('users').where('username=?', (username,)).getField('id')
    salt = M('users').where('id=?', (uid,)).getField('salt')
    return md5(md5(password + '_bt.cn') + salt)


def get_php_versions(reverse=False):
    _file = get_panel_path() + '/config/php_versions.json'
    if os.path.exists(_file):
        version_list = json.loads(readFile(_file))
    else:
        version_list = ['52', '53', '54', '55', '56', '70', '71', '72', '73', '74', '80', '81', '82', '83','84']

    return sorted(version_list, reverse=reverse)

def GetLocalIp():
    #取本地外网IP
    try:
        filename = get_panel_path() + '/data/iplist.txt'
        ipaddress = ReadFile(filename)
        if not ipaddress:
            url = GetConfigValue('home') + '/Api/getIpAddress'
            m_str = HttpGet(url)
            ipaddress = re.search(r"^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$",m_str).group(0)
            WriteFile(filename,ipaddress)
        c_ip = check_ip(ipaddress)
        return ipaddress
    except:
       
        url = GetConfigValue('home') + '/Api/getIpAddress'
        return HttpGet(url)

def get_server_ip():
    """
    @获取服务器外网ip
    """

    user_file = '{}/data/userInfo.json'.format(get_panel_path())
    if os.path.exists(user_file):
        try:
            userTmp = json.loads(readFile(user_file))
            return userTmp['address']
        except:
            pass
    return GetLocalIp()

# 获取服务器内网Ip
def get_local_ip():
    try:
        ret = ExecShell("ip addr | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -E -v \"^127\.|^255\.|^0\.\" | head -n 1")
        local_ip = ret[0].strip()
        return local_ip
    except:
        return '127.0.0.1'

def get_network_ip():
    """
    @name 获取本机ip
    @return string
    """

    import socket
    s = None
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
        return ip
    except Exception:
        return '127.0.0.1'
    finally:
        if s is not None:
            s.close()

def get_push_info(title, slist=[]):
    """
    @name 获取推送信息
    @param title<str> 推送标题
    @param slist<list> 推送追加的列表
            如：slist = ['>发送内容:xxx']
    @return dict
    """
    data = {}
    data['title'] = title
    data['ip'] = get_server_ip()

    data['local_ip'] = get_network_ip()
    data['time'] = format_date()
    data['server_name'] = GetConfigValue('title')

    dlist = [
        "#### {}".format(data['title']),
        ">服务器：" + data['server_name'],
        ">IP地址：{}(外) {}(内)".format(data['ip'], data['local_ip']),
        ">发送时间：" + data['time']
    ]
    dlist.extend(slist)
    msg = "\n\n".join(dlist)
    data['msg'] = msg
    data['list'] = dlist
    return data

def getPanelAddr():
    
    protocol = 'http'
    panel_path = get_panel_path()
    if os.path.exists(panel_path + '/data/ssl.pl'):
        protocol = 'https'
    
    port = "8888"
    if os.path.exists(panel_path + '/data/port.pl'):
        port = ReadFile(panel_path + '/data/port.pl').strip()
    
    url =  "{}://{}:{}".format(protocol, GetLocalIp(), port)
    return url

def GetClientIp():
    return GetLocalIp()

def checkIp(ip):
    p = re.compile('^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
    if p.match(ip):
        return True
    else:
        return False

#判断是否IP地址(ipv4+ipv6)  
def check_ip(ip):
    return is_ipv4(ip) or is_ipv6(ip)

def is_ipv4(ip):
    try:
        socket.inet_pton(socket.AF_INET, ip)
    except AttributeError:
        try:
            socket.inet_aton(ip)
        except socket.error:
            return False
        return ip.count('.') == 3
    except socket.error:
        return False
    return True

def is_ipv6(ip):
    try:
        socket.inet_pton(socket.AF_INET6, ip)
    except socket.error:
        return False
    return True

# 判断是否x64系统
def is_64bitos():
    import platform
    bites = {'AMD64': 64, 'x86_64': 64, 'i386': 32, 'x86': 32}
    info = platform.uname()
    if bites.get(info.machine) == 64:
        return True
    return False

#设置系统环境变量
def set_system_path(key, val):
    ExecShell('setx /m ' + key + ' "' + val + '"')
    if os.environ.get(key):
        return True
    return False

def get_sys_version():
    import platform
    v = platform.version()
    arrs = v.split('.')
    arrs.append(v)
    return arrs

def get_url(timeout=0.5):
    return  'http://download.bt.cn'


def submit_panel_bug(err_msg=None):
    pass