# -*- coding:utf-8 -*-

import nacos
import yaml
import platform
import string
import mongoengine
import redis
from redis.sentinel import Sentinel


def trim(s):
    import re
    if s.startswith(' ') or s.endswith(' '):
        return re.sub(r"^(\s+)|(\s+)$", "", s)
    return s


def nacos_main(nacosConf):
    if nacosConf is None:
        nacos_client = nacos.NacosClient('192.168.1.31:9003', namespace='2288830d-a768-4971-c814-14d227d544d2',
                                         username='nacos', password='nacos')
        nacos_config = nacos_client.get_config('AnalysisProvider.yaml', 'DEFAULT_GROUP', 5000)
    else:
        nacos_client = nacos.NacosClient(getHostIP(nacosConf["nacos_server"]), namespace=nacosConf["nacos_namespace"],
                                         username=nacosConf["nacos_user"], password=nacosConf["nacos_password"])
        nacos_config = nacos_client.get_config(nacosConf['nacos_data_id'], nacosConf['nacos_group'], 5000)
    
    nacos_config_dict = yaml.load(nacos_config, Loader=yaml.FullLoader)
    cs_text = nacos_config_dict["spring"]["data"]["mongodbConfig"]
    rs_text = nacos_config_dict["spring"]["redis"]
    
    if nacos_config_dict["spring"]["data"].get('maxResponseCount') is not None:
        maxResponseCount = nacos_config_dict["spring"]["data"]['maxResponseCount']
    else:
        maxResponseCount = 500
    
    mongodb_cfg_map, redis_cfg_map, templateFileServerUrlMap, templateUrl = {}, {}, {}, ''
    
    for i in cs_text:
        if i != "":
            plat = i["plat"]
            if ',' in plat:
                plats = plat.split(',')
            else:
                plats = [plat]
            
            for plat in plats:
                plat = trim(plat)
                mongodb_cfg = {}
                
                if str(i["uri"]).find('replicaSet=') > 0:
                    mongodb_cfg["uri"] = str(i["uri"])
                    mongodb_cfg["host"] = ""
                    mongodb_cfg["port"] = "0"
                    mongodb_cfg["db_name"] = ""
                    mongodb_cfg["user"] = ""
                    mongodb_cfg["password"] = ""
                else:
                    cfg_1 = i["uri"]
                    cfg_1 = cfg_1.replace('mongodb://', '')
                    cfg_1 = cfg_1.split("/")
                    
                    host_port = cfg_1[0]
                    # 从最后一个冒号分割，处理主机名包含点号的情况
                    if ':' in host_port:
                        last_colon_index = host_port.rfind(':')
                        mongodb_cfg["host"] = host_port[:last_colon_index]
                        mongodb_cfg["port"] = host_port[last_colon_index + 1]
                    else:
                        mongodb_cfg["host"] = host_port
                        mongodb_cfg["port"] = "27017"
                    
                    if len(cfg_1) > 1:
                        mongodb_cfg["db_name"] = cfg_1[1]
                    else:
                        mongodb_cfg["db_name"] = "admin"
                    
                    if i["user"] is not None and i["user"] != '':
                        mongodb_cfg["user"] = i["user"]
                        mongodb_cfg["password"] = i["password"]
                    else:
                        mongodb_cfg["user"] = ""
                        mongodb_cfg["password"] = ""
                    
                    mongodb_cfg["uri"] = None
                
                mongodb_cfg_map[plat] = mongodb_cfg
                if i["templateFileServerUrl"] is not None or i["templateFileServerUrl"] != '':
                    if str(i["templateFileServerUrl"]).find('http://') > -1 or \
                            str(i["templateFileServerUrl"]).find('https://') > -1:
                        templateUrl = i["templateFileServerUrl"]
                    else:
                        templateUrl = 'https://' + plat + str(i["templateFileServerUrl"])
                templateFileServerUrlMap[plat] = templateUrl
    redis_cfg_map["host"] = rs_text["host"]
    redis_cfg_map["password"] = rs_text["password"]
    redis_cfg_map["port"] = rs_text["port"]
    redis_cfg_map["namespace"] = rs_text["namespace"]
    if 'mymaster' in rs_text.keys():
        redis_cfg_map["mymaster"] = rs_text["mymaster"]
    else:
        redis_cfg_map["mymaster"] = 'mymaster'
    redis_connect = get_redis_connect(redis_cfg_map)
    redis_cfg_map['redis_connect'] = redis_connect

    return mongodb_cfg_map, redis_cfg_map, templateFileServerUrlMap, maxResponseCount


def nacos_fast(serverUrl, mongodb_cfg_map, templateFileServerUrlMap):
    if serverUrl in mongodb_cfg_map:
        mongodb_cfg, template_url = mongodb_cfg_map[serverUrl], templateFileServerUrlMap[serverUrl]
    else:
        if 'default' in mongodb_cfg_map:
            mongodb_cfg, template_url = mongodb_cfg_map['default'], templateFileServerUrlMap['default']
        else:
            mongodb_cfg, template_url = '', ''
    
    return mongodb_cfg, template_url


def getHostIP(hostName):
    """获取主机名对应的IP地址"""
    hostNameReturn = hostName
    
    # 处理包含多个主机的情况（如 MongoDB 副本集）
    if ',' in hostName:
        return hostName
    
    hostNameAll = str(hostName).split(':')
    if platform.system() == 'Windows':
        HOSTS_PATH = r'C:\WINDOWS\system32\drivers\etc\HOSTS'
    else:
        HOSTS_PATH = r'/etc/hosts'
    try:
        with open(HOSTS_PATH, 'r', encoding='utf-8', errors='ignore') as f:
            hostlines = f.readlines()
        hostlines = [line.strip() for line in hostlines
                     if not line.startswith('#') and line.strip() != '']
        hosts = []
        for line in hostlines:
            if len(line.split('#')[0].split()) > 1:
                hostips = line.split('#')[0].split()[0]
                hostnames = line.split('#')[0].split()[1]
                hosts.append({hostnames: hostips})
        for hostItem in hosts:
            if hostNameAll[0] in hostItem.keys():
                hostNameReturn = hostItem[hostNameAll[0]] + ':' + hostNameAll[1]
    except Exception as e:
        print(f"读取 hosts 文件失败: {e}")
    return hostNameReturn

def get_redis_connect(redis_cfg):
    master = None
    try:
        if str(redis_cfg['host']).find(',') > -1:
            host_list = str(redis_cfg['host']).split(',')
            port_list = str(redis_cfg['port']).split(',')
            host_port_list = []
            for host_list_index, host_list_item in enumerate(host_list):
                if host_list_index < len(port_list):
                    host_port_list.append((host_list_item, int(port_list[host_list_index])))
                else:
                    host_port_list.append((host_list_item, int(port_list[0])))
            sentinel = Sentinel(host_port_list)
            master = sentinel.master_for(redis_cfg['mymaster'], socket_timeout=1000, password=redis_cfg['password'],
                                         decode_responses=False)
        else:
            master = redis.Redis(host=redis_cfg['host'], port=redis_cfg['port'], password=redis_cfg['password'],
                                 decode_responses=False)
    except Exception as ex:
        print(ex)
    finally:
        return master