/*
 *    Copyright (c) 2018-2025, hnqz All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: hnqz
 */

package net.yyc.common.gray.nacos;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery;
import com.alibaba.cloud.nacos.ribbon.ExtendBalancer;
import com.alibaba.nacos.api.naming.pojo.Instance;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.yyc.common.core.constant.CommonConstants;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 跨 Nacos Group 实例选择：按目标 group + serviceName 查询，绕过仅使用消费者自身
 * {@code discovery.group} 的实例发现限制。
 */
@Slf4j
@RequiredArgsConstructor
public class NacosCrossGroupInstanceSelector {

	private final NacosDiscoveryProperties nacosDiscoveryProperties;

	/**
	 * @param version 请求头 {@link CommonConstants#VERSION}，无则按权重随机
	 */
	public ServiceInstance choose(NacosGroupService groupService, String version) {
		try {
			List<Instance> instances = nacosDiscoveryProperties.namingServiceInstance()
				.selectInstances(groupService.getServiceName(), groupService.getGroup(), true);
			if (CollectionUtils.isEmpty(instances)) {
				log.warn("[跨Group路由] Nacos 无可用实例, group={}, service={}", groupService.getGroup(),
						groupService.getServiceName());
				return null;
			}
			Instance instance = selectInstance(instances, version);
			log.debug("[跨Group路由] 选中实例 group={}, service={}, target={}:{}", groupService.getGroup(),
					groupService.getServiceName(), instance.getIp(), instance.getPort());
			return NacosServiceDiscovery.hostToServiceInstance(instance, groupService.getServiceName());
		}
		catch (Exception e) {
			log.error("[跨Group路由] Nacos 查询失败, group={}, service={}", groupService.getGroup(),
					groupService.getServiceName(), e);
			return null;
		}
	}

	private Instance selectInstance(List<Instance> instances, String version) {
		if (StringUtils.hasText(version)) {
			for (Instance instance : instances) {
				String targetVersion = instance.getMetadata().get(CommonConstants.VERSION);
				if (version.equalsIgnoreCase(targetVersion)) {
					return instance;
				}
			}
		}
		return ExtendBalancer.getHostByRandomWeight2(instances);
	}

}
