#!/bin/bash
#
# 测试公共函数库
#

# 注意：不在库文件中设置 set -e，由调用脚本控制

# 配置
BASE_URL="${BASE_URL:-http://localhost:4000}"
TEST_TIMESTAMP="${TEST_TIMESTAMP:-$(date +%s)}"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# ========================================
# 辅助函数
# ========================================

# 打印带颜色的信息
info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

success() {
    echo -e "${GREEN}[PASS]${NC} $1"
}

error() {
    echo -e "${RED}[FAIL]${NC} $1"
}

warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

# 检查上一个命令是否成功（传递状态码）
# $1: 描述
# $2: 状态码（可选，默认使用 $?）
check_success() {
    local status=${2:-$?}
    if [ $status -eq 0 ]; then
        success "$1"
        return 0
    else
        error "$1"
        return 1
    fi
}

# 检查上一个命令是否失败（用于测试权限拒绝）
check_fail() {
    if [ $? -ne 0 ]; then
        success "$1 (预期失败)"
        return 0
    else
        error "$1 (应该失败但没有)"
        return 1
    fi
}

# 检查HTTP响应码
# $1: 响应内容
# $2: 期望状态码（默认 200）
check_http_code() {
    local response="$1"
    local expected="${2:-200}"
    local code

    # 处理空响应（成功时可能返回空体）
    if [ -z "$response" ]; then
        code="200"
    else
        # 提取 code 字段，如果不存在则认为是 200
    local json_code
    json_code=$(echo "$response" | jq -r '.code // empty')
    
    if [ -z "$json_code" ] || [ "$json_code" = "empty" ]; then
        code="200"
    elif [[ "$json_code" =~ ^[0-9]+$ ]]; then
        code="$json_code"
    else
        # code 字段存在但不是数字（可能是业务字段，如 org.code），视为成功 200
        code="200"
    fi
    fi

    if [ "$code" = "$expected" ]; then
        return 0
    else
        error "期望状态码: $expected, 实际: $code"
        info "响应: $response"
        return 1
    fi
}

# 检查服务是否运行
check_service() {
    if ! curl -s "$BASE_URL/api/auth/login-methods" > /dev/null 2>&1; then
        error "服务未启动，请先启动服务"
        info "运行: go run cli/main.go -db.type=sqlite -db.dsn /tmp/vb.sqlite -p 4000"
        exit 1
    fi
    success "服务正在运行"
}

# ========================================
# API 请求封装
# ========================================

# GET 请求
api_get() {
    local path="$1"
    local token="${2:-}"

    local curl_opts=("-s" "-X" "GET")

    if [ -n "$token" ]; then
        curl_opts+=("-H" "Authorization: Bearer $token")
    fi

    curl "${curl_opts[@]}" "$BASE_URL$path"
}


# POST 请求
api_post() {
    local path="$1"
    local data="$2"
    local token="${3:-}"
    local extra_headers="${4:-}"

    local curl_opts=("-s" "-X" "POST" "-H" "Content-Type: application/json")

    if [ -n "$token" ]; then
        curl_opts+=("-H" "Authorization: Bearer $token")
    fi

    if [ -n "$extra_headers" ]; then
        # 将 extra_headers 按空格分割添加到数组
        for header in $extra_headers; do
            curl_opts+=("-H" "$header")
        done
    fi

    curl "${curl_opts[@]}" "$BASE_URL$path" -d "$data"
}

# PATCH 请求
api_patch() {
    local path="$1"
    local data="$2"
    local token="${3:-}"
    local extra_headers="${4:-}"

    local curl_opts=("-s" "-X" "PATCH" "-H" "Content-Type: application/json")

    if [ -n "$token" ]; then
        curl_opts+=("-H" "Authorization: Bearer $token")
    fi

    if [ -n "$extra_headers" ]; then
        for header in $extra_headers; do
            curl_opts+=("-H" "$header")
        done
    fi

    curl "${curl_opts[@]}" "$BASE_URL$path" -d "$data"
}

# DELETE 请求
api_delete() {
    local path="$1"
    local token="${2:-}"
    local extra_headers="${3:-}"

    local curl_opts=("-s" "-X" "DELETE")

    if [ -n "$token" ]; then
        curl_opts+=("-H" "Authorization: Bearer $token")
    fi

    if [ -n "$extra_headers" ]; then
        for header in $extra_headers; do
            curl_opts+=("-H" "$header")
        done
    fi

    curl "${curl_opts[@]}" "$BASE_URL$path"
}

# ========================================
# 用户相关操作
# ========================================

# 注册用户
# 返回: 注册响应
register_user() {
    local username="$1"
    local password="$2"
    local email="$3"

    api_post "/api/auth/register" \
        "{\"username\": \"$username\", \"password\": \"$password\", \"email\": \"$email\"}"
}

# 登录用户
# 返回: 登录响应
login_user() {
    local username="$1"
    local password="$2"

    api_post "/api/auth/login" \
        "{\"username\": \"$username\", \"password\": \"$password\"}"
}

# 提取 access_token
get_token() {
    local login_response="$1"
    echo "$login_response" | jq -r '.access_token'
}

# 提取 refresh_token
get_refresh_token() {
    local login_response="$1"
    echo "$login_response" | jq -r '.refresh_token'
}

# 提取用户ID
get_user_id() {
    local login_response="$1"
    echo "$login_response" | jq -r '.user.id'
}

# ========================================
# 组织相关操作
# ========================================

# 创建组织
create_org() {
    local token="$1"
    local code="$2"
    local name="$3"
    local desc="${4:-}"

    api_post "/api/orgs" \
        "{\"code\": \"$code\", \"name\": \"$name\", \"description\": \"$desc\"}" \
        "$token"
}

# 更新组织
update_org() {
    local token="$1"
    local org_id="$2"
    local data="$3"

    api_patch "/api/orgs/$org_id" "$data" "$token" "-H X-Org-ID: $org_id"
}

# 添加组织成员
add_org_member() {
    local token="$1"
    local org_id="$2"
    local user_id="$3"
    local role="${4:-member}"

    api_post "/api/orgs/$org_id/members" \
        "{\"user_id\": \"$user_id\", \"role\": \"$role\"}" \
        "$token" \
        "-H X-Org-ID: $org_id"
}

# ========================================
# 测试框架
# ========================================

# 测试开始
test_start() {
    local name="$1"
    echo ""
    echo "========================================"
    echo "测试: $name"
    echo "BASE_URL: $BASE_URL"
    echo "========================================"
}

# 测试步骤
step() {
    echo ""
    info "$1"
}

# 测试结束
test_end() {
    echo ""
    success "测试完成"
}
