/*
url的格式如下：https://cmq-{$type}-{$region}.api.{$network}.com
其最终内容受到以下因素的影响：地域、网络、消息队列模型

地域
gz（广州）、sh（上海）、bj（北京）、shjr（上海金融）、szjr（深圳金融）、hk（中国香港）、cd（成都）、ca(北美)、usw（美西）、use（美东）、in（印度）、th（泰国）、sg（新加坡）

网络
外网接口请求域名后缀：api.qcloud.com
内网接口请求域名后缀：api.tencentyun.com

队列模型
请参照下面说明将域名中的 {$region} 替换成相应地域：
外网接口请求域名：https://cmq-queue-{$region}.api.qcloud.com
内网接口请求域名：http://cmq-queue-{$region}.api.tencentyun.com

主题模型
请参照下面说明将域名中的 {$region} 替换成相应地域：
外网接口请求域名：https://cmq-topic-{$region}.api.qcloud.com
内网接口请求域名：http://cmq-topic-{$region}.api.tencentyun.com
*/
package mqMgr

import (
	"fmt"
	"strings"

	"goutil/securityUtil"
	"goutil/stringUtil"
	"goutil/webUtil"
)

func getPrefix(network string) string {
	if network == MQ_NETWORK_INTERNAL {
		return "http://"
	}

	return "https://"
}

// // 获取请求url
// // region:地域
// // network:网络类型：内网、外网
// // _type:消息队列类型：消息队列、消息主题
// // 返回：
// // 请求url
// func getHost(region, network, _type string) string {
// 	url := "cmq-{$type}-{$region}.api.{$network}.com"
// 	url = strings.Replace(url, "{$region}", region, 1)
// 	url = strings.Replace(url, "{$network}", network, 1)
// 	url = strings.Replace(url, "{$type}", _type, 1)

// 	return url
// }

// 获取请求url todo:切换成tdmq之后需要用这个方法
// region:地域
// network:网络类型：内网、外网
// _type:消息队列类型：消息队列、消息主题
// 返回：
// 请求url
func getHost(region, network, _type string) string {
	var url string = ""
	if network == MQ_NETWORK_INTERNAL {
		url = "{$region}.mqadapter.cmq.{$network}.com"
	} else {
		url = "cmq-{$region}.public.{$network}.com"
	}

	url = strings.Replace(url, "{$region}", region, 1)
	url = strings.Replace(url, "{$network}", network, 1)

	return url
}

func getPath() string {
	return "/v2/index.php"
}

func getMethod() string {
	return "POST"
}

// AssembleUrl 组装请求url
// 参数
// region:地域
// network:网络类型：内网、外网
// _type:消息队列类型：消息队列、消息主题
// secretKey:密钥的key
// paramMap:参数字典
// 返回值
// string:组装好的请求url
// string:签名
// error:错误
func AssembleUrl(region, network, _type, secretKey string, paramMap map[string]string) (url, signature string, err error) {
	// 1. 申请安全凭证（已经得到）

	// 2. 生成签名串
	// 2.1、对参数排序
	// 2.2、拼接请求字符串
	// 注意：
	// “参数值”为原始值而非 url 编码后的值。
	// 若输入参数中包含下划线，则需要将其转换为“.”。(指的是参数的名称，不是参数的值)
	paramStr := webUtil.AssembleRequestParamSort(paramMap, true)

	// 2.3、拼接签名原文字符串
	host := getHost(region, network, _type)
	path := getPath()
	signatureSource := fmt.Sprintf("%s%s%s?%s", getMethod(), host, path, paramStr)

	// 2.4、生成签名串
	data, err := securityUtil.HmacSha256(signatureSource, secretKey)
	if err != nil {
		return
	}
	signature = string(stringUtil.Base64Encode2(data))

	// 3. 签名串编码
	// 注意：
	// 生成的签名串并不能直接作为请求参数，需要对其进行 URL 编码。
	// 如果用户的请求方法是 GET，则对所有请求参数值均需要做 URL 编码。
	// 如果是POST，则不用进行URL编码
	// signature = url.QueryEscape(signature)

	// 将签名添加到参数集合中
	url = fmt.Sprintf("%s%s%s", getPrefix(network), host, path)

	return
}
