// Package server 提供 HTTP 服务器的核心实现，支持单服务器和虚拟主机两种运行模式。
//
// 该文件包含虚拟主机管理相关的核心逻辑，包括：
//   - 虚拟主机管理器的创建和配置
//   - 基于 Host 头的请求分发
//   - 默认主机 fallback 机制
//
// 主要用途：
//
//	用于支持多域名虚拟主机场景，根据请求的 Host 头分发到不同的处理器。
//
// 注意事项：
//   - 所有方法均为并发安全
//   - 未匹配的 Host 头请求由默认主机处理
//
// 作者：xfy
package server

import (
	"fmt"
	"regexp"
	"strings"

	"github.com/valyala/fasthttp"
	"rua.plus/lolly/internal/netutil"
	"rua.plus/lolly/internal/utils"
)

// VHostManager 虚拟主机管理器。
//
// 管理多个虚拟主机，根据请求的 Host 头分发到对应的处理器。
// 支持默认主机作为未匹配请求的 fallback。
// 支持精确匹配、前缀通配（*.example.com）、后缀通配（example.*）和正则匹配。
type VHostManager struct {
	hosts             map[string]*VirtualHost
	wildcardSuffixMap map[string]*VirtualHost // suffix -> vhost
	wildcardTLDMap    map[string]*VirtualHost // TLD -> vhost
	regexHosts        []*RegexHostMatcher
	defaultHost       *VirtualHost
}

// RegexHostMatcher 正则主机匹配器。
type RegexHostMatcher struct {
	vhost   *VirtualHost
	pattern *regexp.Regexp
}

// VirtualHost 虚拟主机。
//
// 代表一个虚拟主机配置，包含名称和对应的请求处理器。
type VirtualHost struct {
	// handler 请求处理器
	handler fasthttp.RequestHandler

	// name 虚拟主机名称（域名）
	name string
}

// NewVHostManager 创建虚拟主机管理器。
//
// 返回值：
//   - *VHostManager: 新创建的管理器实例
func NewVHostManager() *VHostManager {
	return &VHostManager{
		hosts:             make(map[string]*VirtualHost),
		wildcardSuffixMap: make(map[string]*VirtualHost),
		wildcardTLDMap:    make(map[string]*VirtualHost),
		regexHosts:        make([]*RegexHostMatcher, 0),
	}
}

// AddHost 添加虚拟主机。
//
// 支持以下 server_name 格式：
//   - 精确匹配: "example.com"
//   - 前缀通配: "*.example.com"（匹配任意子域名）
//   - 后缀通配: "example.*"（匹配任意 TLD）
//   - 正则匹配: "~regex"（以 ~ 开头，后面是正则表达式）
//
// 参数：
//   - name: 虚拟主机名称（域名）
//   - handler: 请求处理器
//
// 返回值：
//   - error: 正则表达式无效时返回错误
func (v *VHostManager) AddHost(name string, handler fasthttp.RequestHandler) error {
	if strings.HasPrefix(name, "~") {
		// 正则匹配
		pattern := name[1:]
		re, err := regexp.Compile(pattern)
		if err != nil {
			return fmt.Errorf("invalid regex pattern: %w", err)
		}
		v.regexHosts = append(v.regexHosts, &RegexHostMatcher{
			pattern: re,
			vhost: &VirtualHost{
				name:    name,
				handler: handler,
			},
		})
		return nil
	} else if strings.HasPrefix(name, "*.") {
		// 前缀通配 *.example.com
		suffix := name[2:]
		v.wildcardSuffixMap[suffix] = &VirtualHost{
			name:    name,
			handler: handler,
		}
		return nil
	} else if strings.HasSuffix(name, ".*") {
		// 后缀通配 example.*
		tld := name[:len(name)-2]
		v.wildcardTLDMap[tld] = &VirtualHost{
			name:    name,
			handler: handler,
		}
		return nil
	} else {
		// 精确匹配
		v.hosts[name] = &VirtualHost{
			name:    name,
			handler: handler,
		}
		return nil
	}
}

// SetDefault 设置默认主机。
//
// 参数：
//   - handler: 默认主机的请求处理器
func (v *VHostManager) SetDefault(handler fasthttp.RequestHandler) {
	v.defaultHost = &VirtualHost{
		name:    "default",
		handler: handler,
	}
}

// findLongestWildcardPrefix 查找最长的通配符前缀匹配。
//
// 按 nginx 规则，从最长子域名开始匹配，例如：
// "a.b.example.com" 优先匹配 "*.b.example.com"，其次 "*.example.com"。
//
// 参数：
//   - host: 主机名
//
// 返回值：
//   - *VirtualHost: 匹配的虚拟主机，未匹配返回 nil
func (v *VHostManager) findLongestWildcardPrefix(host string) *VirtualHost {
	parts := strings.Split(host, ".")
	for i := 1; i < len(parts); i++ {
		suffix := strings.Join(parts[i:], ".")
		if vhost, ok := v.wildcardSuffixMap[suffix]; ok {
			return vhost
		}
	}
	return nil
}

// FindHost 根据主机名查找虚拟主机。
//
// 匹配优先级（nginx server_name 规则）：
//  1. 精确匹配
//  2. 最长前缀通配（*.example.com）
//  3. 后缀通配（example.*）
//  4. 正则匹配（按配置顺序）
//  5. 默认主机
//
// 参数：
//   - host: 主机名
//
// 返回值：
//   - *VirtualHost: 匹配的虚拟主机
func (v *VHostManager) FindHost(host string) *VirtualHost {
	// 1. 精确匹配
	if vhost, ok := v.hosts[host]; ok {
		return vhost
	}

	// 2. 最长前缀通配 *.example.com
	if vhost := v.findLongestWildcardPrefix(host); vhost != nil {
		return vhost
	}

	// 3. 后缀通配 example.*
	parts := strings.Split(host, ".")
	if len(parts) >= 2 {
		tld := parts[0]
		if vhost, ok := v.wildcardTLDMap[tld]; ok {
			return vhost
		}
	}

	// 4. 正则匹配（按配置顺序）
	for _, m := range v.regexHosts {
		if m.pattern.MatchString(host) {
			return m.vhost
		}
	}

	// 5. 默认主机
	return v.defaultHost
}

// Handler 返回虚拟主机选择器。
//
// 返回值：
//   - fasthttp.RequestHandler: 根据 Host 头分发请求的处理器
func (v *VHostManager) Handler() fasthttp.RequestHandler {
	return func(ctx *fasthttp.RequestCtx) {
		host := netutil.StripPort(string(ctx.Host()))

		if vhost := v.FindHost(host); vhost != nil {
			vhost.handler(ctx)
		} else {
			utils.SendError(ctx, utils.ErrNotFound)
		}
	}
}
