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

import redis
from redis.cluster import ClusterNode
from redis.cluster import RedisCluster
from redis.sentinel import Sentinel

from liquiclient.config import get_property


# 获取redis实例
def get_redis_client():
    mode = get_property("redis.mode")
    host = get_property("redis.host")
    port = get_property("redis.port")
    username = get_property("redis.username")
    password = get_property("redis.password")

    if mode == "sentinel":
        # 哨兵模式处理
        # host格式: "host1:port1,host2:port2,host3:port3"
        service_name = get_property("redis.sentinel")

        client = get_sentinel_client(host, port, service_name, username, password)

    elif mode == "cluster":
        # 集群模式处理 - 修正URL构建，包含端口号
        client = get_cluster_client(host, port, username, password)
    else:

        client = get_master_client(host, port, username, password)

    return client


# 获取redis实例
def get_redis_cluster_client(key):
    mode = get_property("redis.mode")
    host = get_property(key + ".redis.host")
    port = get_property(key + ".redis.port")
    username = get_property(key + ".redis.username")
    password = get_property(key + ".redis.password")

    if mode == "sentinel":
        # 哨兵模式处理
        # host格式: "host1:port1,host2:port2,host3:port3"
        service_name = get_property(key + ".redis.sentinel")

        client = get_sentinel_client(host, port, service_name, username, password)

    elif mode == "cluster":
        client = get_cluster_client(host, port, username, password)
    else:

        client = get_master_client(host, port, username, password)

    return client


def get_sentinel_client(host, port, service_name="mymaster", username=None, password=None):
    # 解析哨兵主机列表
    if isinstance(host, str):
        sentinel_list = []
        for host_port in host.split(','):
            host_port = host_port.strip()
            if ':' in host_port:
                h, p = host_port.split(':', 1)
                sentinel_list.append((h.strip(), int(p.strip())))
            else:
                sentinel_list.append((host_port, port))
    else:
        # 如果没有配置哨兵主机列表，使用默认配置
        sentinel_list = [(host, int(port) if port else 26379)]

    # 创建哨兵实例
    sentinel_kwargs = {}
    if username and password:
        sentinel_kwargs['username'] = username
        sentinel_kwargs['password'] = password
    elif password:
        sentinel_kwargs['password'] = password

    sentinel = Sentinel(sentinel_list, **sentinel_kwargs)

    # 获取主节点连接
    master_kwargs = {}
    if username and password:
        master_kwargs['username'] = username
        master_kwargs['password'] = password
    elif password:
        master_kwargs['password'] = password

    return sentinel.master_for(service_name, **master_kwargs)


def get_master_client(host, port, username=None, password=None):
    # 单机模式处理
    # 构建连接参数，只包含非空的认证信息
    connection_params = {
        'host': host,
        'port': port
    }

    # 只有当username和password都不为空时才添加认证参数
    if username and password:
        connection_params['username'] = username
        connection_params['password'] = password
    elif password:  # 只有密码没有用户名的情况
        connection_params['password'] = password

    return redis.Redis(**connection_params)


def get_cluster_client(host, port, username=None, password=None):
    # 集群模式处理 - 统一用node方式。 阿里云是有代理不是用的是Redis.from_url("redis://localhost:6379/0")
    #  url = "redis://{}:{}@{}:{}".format(quote(username), quote(password), host, port)
    node_list = []
    for host_port in host.split(','):
        host_port = host_port.strip()
        if ':' in host_port:
            h, p = host_port.split(':', 1)
            node_list.append(ClusterNode(h.strip(), int(p.strip())))
        else:
            node_list.append(ClusterNode(host_port, port))

    if username and password:
        return RedisCluster(startup_nodes=node_list, username=username, password=password)
    elif password:
        return RedisCluster(startup_nodes=node_list, password=password)
    else:
        return RedisCluster(startup_nodes=node_list)
