package l7

import (
	"bytes"
	"strconv"
	"strings"
)

func ParseHttp(payload []byte) (string, string) {
	method, rest, ok := bytes.Cut(payload, space)
	if !ok {
		return "", ""
	}
	if !isHttpMethod(string(method)) {
		return "", ""
	}
	uri, _, ok := bytes.Cut(rest, space)
	if !ok {
		uri = append(uri, []byte("...")...)
	}
	return string(method), string(uri)
}

// parseHttpHeader 解析 HTTP 头部字段的值
func parseHttpHeader(payload []byte, headerName string) string {
	headerBytes := []byte(headerName)
	headerIdx := bytes.Index(payload, headerBytes)
	if headerIdx == -1 {
		return ""
	}

	headerStart := headerIdx + len(headerBytes)
	if headerStart >= len(payload) {
		return ""
	}

	// 查找头部值的结束位置（\r\n）
	headerEnd := bytes.Index(payload[headerStart:], []byte("\r\n"))
	if headerEnd == -1 {
		// 如果没有找到 \r\n，使用剩余数据的长度
		headerEnd = len(payload) - headerStart
	}

	if headerEnd <= 0 {
		return ""
	}

	headerValue := payload[headerStart : headerStart+headerEnd]
	return string(bytes.TrimSpace(headerValue))
}

// parseHttpHostCommon 解析 HTTP 请求的公共逻辑，返回 method, requestURI, host, port, rest
// rest 是解析完 method 和 uri 后剩余的 payload 部分，用于后续解析其他头部
func parseHttpHostCommon(payload []byte, isTls bool) (string, string, string, uint16, []byte) {
	method, rest, ok := bytes.Cut(payload, space)
	if !ok {
		return "", "", "", 0, nil
	}
	if !isHttpMethod(string(method)) {
		return "", "", "", 0, nil
	}

	uri, rest, ok := bytes.Cut(rest, space)
	if !ok {
		uri = append(uri, []byte("...")...)
	}

	// 解析 Host 头部
	hostPort := parseHttpHeader(rest, "Host:")
	if hostPort == "" {
		return string(method), string(uri), "", 0, rest
	}

	hostParts := strings.Split(hostPort, ":")
	host := hostParts[0]

	// 根据 TLS 标识设置默认端口
	var port uint16
	if isTls {
		port = 443 // HTTPS 默认端口
	} else {
		port = 80 // HTTP 默认端口
	}

	// 如果 Host 头部明确指定了端口，使用指定的端口
	if len(hostParts) > 1 {
		port64, err := strconv.ParseUint(hostParts[1], 10, 16)
		if err == nil {
			port = uint16(port64)
		}
	}

	return string(method), string(uri), host, port, rest
}

// ParseHttpHost 解析 HTTP 请求，返回 method, requestURI, host, port
// 不解析 User-Agent，性能更优
func ParseHttpHost(payload []byte, isTls bool) (string, string, string, uint16) {
	method, uri, host, port, _ := parseHttpHostCommon(payload, isTls)
	return method, uri, host, port
}

// ParseHttpHostWithUserAgent 解析 HTTP 请求，返回 method, requestURI, host, port, userAgent
// 包含 User-Agent 解析，适用于需要 User-Agent 信息的场景
func ParseHttpHostWithUserAgent(payload []byte, isTls bool) (string, string, string, uint16, string) {
	method, uri, host, port, rest := parseHttpHostCommon(payload, isTls)
	// 解析 User-Agent 头部
	userAgent := parseHttpHeader(rest, "User-Agent:")
	return method, uri, host, port, userAgent
}

// ParseHttpSysvcFrom 解析 HTTP 请求中的 cwother 头部，兼容常见大小写写法。
func ParseHttpSysvcFrom(payload []byte) string {
	for _, headerName := range []string{"CWOTHER:", "Cwother:", "cwother:"} {
		if value := parseHttpHeader(payload, headerName); value != "" {
			return value
		}
	}
	return ""
}

// ParseElasticsearch 解析 Elasticsearch HTTP 请求体
// 只返回请求体（Query）部分
func ParseElasticsearch(payload []byte) string {
	_, _, _, _, rest := parseHttpHostCommon(payload, false)

	// 查找请求体的开始位置（\r\n\r\n 之后）
	bodyStart := bytes.Index(rest, []byte("\r\n\r\n"))
	if bodyStart == -1 {
		// 如果没有找到完整的头部结束标记，返回空字符串
		return ""
	}
	bodyStart += 4

	// 提取请求体（限制长度，避免过长）
	body := rest[bodyStart:]
	maxBodyLen := 200
	if len(body) > maxBodyLen {
		body = body[:maxBodyLen]
	}

	// 只返回请求体内容
	bodyStr := strings.TrimSpace(string(body))
	return bodyStr
}
