/*
 *    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 java.util.Optional;

import lombok.extern.slf4j.Slf4j;

/**
 * Nacos 跨 Group 服务名 {@code group@@service} 与 URI 合法 host 之间的编解码。
 * <p>
 * Java {@link java.net.URI} 的 host 不允许 {@code @}、{@code _} 等字符，网关路由 URI 使用
 * {@code group--service}（group 中下划线转为连字符）存储，负载均衡前再还原为 Nacos serviceId。
 * <p>
 * 当路由通过 Spring 标准 {@code PropertiesRouteDefinitionLocator} 加载时，{@code @@} 会被
 * Java URI 解析器 URL 编码为 {@code %40%40}，本类同时处理这两种格式。
 */
@Slf4j
public final class NacosGroupServiceIdCodec {

	private static final String NACOS_GROUP_SERVICE_SEPARATOR = "@@";

	private static final String URI_GROUP_SERVICE_SEPARATOR = "--";

	private static final String URL_ENCODED_SEPARATOR = "%40%40";

	private NacosGroupServiceIdCodec() {
	}

	/**
	 * 将 Nacos 跨 group URI 编码为 URI 合法格式。
	 * <ul>
	 *   <li>{@code lb://cso_hnqz@@hnqz-auth} → {@code lb://cso-hnqz--hnqz-auth}</li>
	 *   <li>{@code lb://cso_hnqz%40%40hnqz-auth} → {@code lb://cso-hnqz--hnqz-auth}</li>
	 * </ul>
	 */
	public static String encodeLbUri(String uri) {
		if (uri == null || !uri.startsWith("lb://")) {
			return uri;
		}
		String hostPart = uri.substring("lb://".length());
		if (hostPart.isEmpty()) {
			return uri;
		}

		String working = hostPart;
		if (working.contains(URL_ENCODED_SEPARATOR)) {
			working = working.replace(URL_ENCODED_SEPARATOR, NACOS_GROUP_SERVICE_SEPARATOR);
		}

		if (!working.contains(NACOS_GROUP_SERVICE_SEPARATOR)) {
			return uri;
		}

		int sep = working.indexOf(NACOS_GROUP_SERVICE_SEPARATOR);
		String group = working.substring(0, sep).replace('_', '-');
		String service = working.substring(sep + NACOS_GROUP_SERVICE_SEPARATOR.length());
		String encoded = "lb://" + group + URI_GROUP_SERVICE_SEPARATOR + service;
		log.debug("[跨Group编解码] URI 编码: {} → {}", uri, encoded);
		return encoded;
	}

	/**
	 * {@code cso-hnqz--hnqz-auth} → {@code cso_hnqz@@hnqz-auth}
	 */
	public static String decodeServiceId(String uriHost) {
		return parseFromUriHost(uriHost).map(gs -> gs.getGroup() + NACOS_GROUP_SERVICE_SEPARATOR + gs.getServiceName())
			.orElse(uriHost);
	}

	/**
	 * 从 URI host（{@code cso-hnqz--hnqz-auth}）解析 group 与 serviceName。
	 */
	public static Optional<NacosGroupService> parseFromUriHost(String uriHost) {
		if (uriHost == null || !uriHost.contains(URI_GROUP_SERVICE_SEPARATOR)) {
			return Optional.empty();
		}
		int sep = uriHost.indexOf(URI_GROUP_SERVICE_SEPARATOR);
		String group = uriHost.substring(0, sep).replace('-', '_');
		String serviceName = uriHost.substring(sep + URI_GROUP_SERVICE_SEPARATOR.length());
		return Optional.of(new NacosGroupService(group, serviceName));
	}

	/**
	 * 从 Nacos serviceId（{@code cso_hnqz@@hnqz-auth}）解析 group 与 serviceName。
	 */
	public static Optional<NacosGroupService> parseFromNacosServiceId(String nacosServiceId) {
		if (nacosServiceId == null || !nacosServiceId.contains(NACOS_GROUP_SERVICE_SEPARATOR)) {
			return Optional.empty();
		}
		int sep = nacosServiceId.indexOf(NACOS_GROUP_SERVICE_SEPARATOR);
		return Optional.of(new NacosGroupService(nacosServiceId.substring(0, sep),
				nacosServiceId.substring(sep + NACOS_GROUP_SERVICE_SEPARATOR.length())));
	}

}
