#!/bin/bash

# QAUP 敏感信息管理脚本

set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
SECRETS_DIR="$PROJECT_ROOT/secrets"
ENV_FILE="$PROJECT_ROOT/.env"

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

print_message() {
    local color=$1
    local message=$2
    echo -e "${color}${message}${NC}"
}

# 生成随机密码
generate_password() {
    local length=${1:-16}
    openssl rand -base64 $length | tr -d "=+/" | cut -c1-$length
}

# 生成强密码
generate_strong_password() {
    local length=${1:-20}
    # 包含大小写字母、数字和特殊字符
    LC_ALL=C tr -dc 'A-Za-z0-9!@#$%^&*' < /dev/urandom | head -c $length
}

# 初始化密钥管理
init_secrets() {
    print_message $BLUE "初始化密钥管理..."
    
    mkdir -p "$SECRETS_DIR"
    chmod 700 "$SECRETS_DIR"
    
    # 生成主密钥
    local master_key_file="$SECRETS_DIR/master.key"
    if [ ! -f "$master_key_file" ]; then
        openssl rand -hex 32 > "$master_key_file"
        chmod 600 "$master_key_file"
        print_message $GREEN "主密钥已生成: $master_key_file"
    fi
    
    # 创建密钥配置文件
    local secrets_config="$SECRETS_DIR/secrets.conf"
    if [ ! -f "$secrets_config" ]; then
        cat > "$secrets_config" << EOF
# QAUP 密钥配置文件
# 此文件包含加密后的敏感信息

# 数据库密码
POSTGRES_PASSWORD_ENCRYPTED=
APP_DB_PASSWORD_ENCRYPTED=

# Redis 密码
REDIS_PASSWORD_ENCRYPTED=

# Token 密钥
TOKEN_SECRET_ENCRYPTED=

# API 密钥
AIRPORT_API_PASSWORD_ENCRYPTED=
EOF
        chmod 600 "$secrets_config"
        print_message $GREEN "密钥配置文件已创建: $secrets_config"
    fi
    
    print_message $GREEN "密钥管理初始化完成"
}

# 加密字符串
encrypt_string() {
    local plaintext="$1"
    local master_key_file="$SECRETS_DIR/master.key"
    
    if [ ! -f "$master_key_file" ]; then
        print_message $RED "错误: 主密钥文件不存在，请先运行 init 命令"
        exit 1
    fi
    
    local master_key=$(cat "$master_key_file")
    echo -n "$plaintext" | openssl enc -aes-256-cbc -a -salt -pass pass:"$master_key"
}

# 解密字符串
decrypt_string() {
    local encrypted="$1"
    local master_key_file="$SECRETS_DIR/master.key"
    
    if [ ! -f "$master_key_file" ]; then
        print_message $RED "错误: 主密钥文件不存在"
        exit 1
    fi
    
    local master_key=$(cat "$master_key_file")
    echo -n "$encrypted" | openssl enc -aes-256-cbc -d -a -pass pass:"$master_key"
}

# 生成所有密码
generate_all_passwords() {
    print_message $BLUE "生成所有密码..."
    
    # 生成数据库密码
    local postgres_password=$(generate_strong_password 20)
    local app_db_password=$(generate_strong_password 20)
    
    # 生成 Redis 密码
    local redis_password=$(generate_strong_password 16)
    
    # 生成 Token 密钥
    local token_secret=$(generate_password 32)
    
    # 生成 API 密码
    local airport_api_password=$(generate_strong_password 16)
    
    print_message $GREEN "密码生成完成："
    echo "PostgreSQL 管理员密码: $postgres_password"
    echo "应用数据库密码: $app_db_password"
    echo "Redis 密码: $redis_password"
    echo "Token 密钥: $token_secret"
    echo "机场 API 密码: $airport_api_password"
    
    # 询问是否保存到配置文件
    read -p "是否将密码保存到环境配置文件? (y/N): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        save_passwords_to_env "$postgres_password" "$app_db_password" "$redis_password" "$token_secret" "$airport_api_password"
    fi
}

# 保存密码到环境文件
save_passwords_to_env() {
    local postgres_password="$1"
    local app_db_password="$2"
    local redis_password="$3"
    local token_secret="$4"
    local airport_api_password="$5"
    
    if [ ! -f "$ENV_FILE" ]; then
        print_message $RED "错误: 环境文件不存在: $ENV_FILE"
        exit 1
    fi
    
    # 备份原文件
    cp "$ENV_FILE" "$ENV_FILE.backup.$(date +%Y%m%d_%H%M%S)"
    
    # 更新密码
    sed -i.tmp "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$postgres_password/" "$ENV_FILE"
    sed -i.tmp "s/^APP_DB_PASSWORD=.*/APP_DB_PASSWORD=$app_db_password/" "$ENV_FILE"
    sed -i.tmp "s/^REDIS_PASSWORD=.*/REDIS_PASSWORD=$redis_password/" "$ENV_FILE"
    sed -i.tmp "s/^TOKEN_SECRET=.*/TOKEN_SECRET=$token_secret/" "$ENV_FILE"
    sed -i.tmp "s/^AIRPORT_API_PASSWORD=.*/AIRPORT_API_PASSWORD=$airport_api_password/" "$ENV_FILE"
    
    rm -f "$ENV_FILE.tmp"
    
    print_message $GREEN "密码已保存到环境文件"
}

# 验证密码强度
validate_password_strength() {
    local password="$1"
    local min_length=8
    local score=0
    
    # 检查长度
    if [ ${#password} -ge $min_length ]; then
        score=$((score + 1))
    fi
    
    # 检查是否包含小写字母
    if [[ "$password" =~ [a-z] ]]; then
        score=$((score + 1))
    fi
    
    # 检查是否包含大写字母
    if [[ "$password" =~ [A-Z] ]]; then
        score=$((score + 1))
    fi
    
    # 检查是否包含数字
    if [[ "$password" =~ [0-9] ]]; then
        score=$((score + 1))
    fi
    
    # 检查是否包含特殊字符
    if [[ "$password" =~ [^a-zA-Z0-9] ]]; then
        score=$((score + 1))
    fi
    
    case $score in
        0-2)
            print_message $RED "密码强度: 弱"
            return 1
            ;;
        3)
            print_message $YELLOW "密码强度: 中等"
            return 0
            ;;
        4-5)
            print_message $GREEN "密码强度: 强"
            return 0
            ;;
    esac
}

# 检查环境文件中的密码
check_env_passwords() {
    print_message $BLUE "检查环境文件中的密码强度..."
    
    if [ ! -f "$ENV_FILE" ]; then
        print_message $RED "错误: 环境文件不存在: $ENV_FILE"
        exit 1
    fi
    
    source "$ENV_FILE"
    
    local weak_passwords=0
    
    # 检查各种密码
    echo "检查 PostgreSQL 密码..."
    if ! validate_password_strength "$POSTGRES_PASSWORD"; then
        weak_passwords=$((weak_passwords + 1))
    fi
    
    echo "检查应用数据库密码..."
    if ! validate_password_strength "$APP_DB_PASSWORD"; then
        weak_passwords=$((weak_passwords + 1))
    fi
    
    if [ -n "$REDIS_PASSWORD" ]; then
        echo "检查 Redis 密码..."
        if ! validate_password_strength "$REDIS_PASSWORD"; then
            weak_passwords=$((weak_passwords + 1))
        fi
    fi
    
    if [ $weak_passwords -eq 0 ]; then
        print_message $GREEN "所有密码强度检查通过"
    else
        print_message $YELLOW "发现 $weak_passwords 个弱密码，建议重新生成"
    fi
}

# 显示帮助信息
show_help() {
    echo "QAUP 敏感信息管理脚本"
    echo ""
    echo "用法: $0 [命令] [选项]"
    echo ""
    echo "命令:"
    echo "  init              初始化密钥管理"
    echo "  generate          生成所有密码"
    echo "  check             检查密码强度"
    echo "  encrypt <text>    加密文本"
    echo "  decrypt <text>    解密文本"
    echo ""
    echo "示例:"
    echo "  $0 init                    # 初始化密钥管理"
    echo "  $0 generate                # 生成所有密码"
    echo "  $0 check                   # 检查密码强度"
    echo "  $0 encrypt 'mypassword'    # 加密密码"
}

# 主函数
main() {
    if [ $# -eq 0 ]; then
        show_help
        exit 0
    fi
    
    local command=$1
    shift
    
    case $command in
        init)
            init_secrets
            ;;
        generate)
            generate_all_passwords
            ;;
        check)
            check_env_passwords
            ;;
        encrypt)
            if [ $# -eq 0 ]; then
                print_message $RED "错误: 请提供要加密的文本"
                exit 1
            fi
            encrypt_string "$1"
            ;;
        decrypt)
            if [ $# -eq 0 ]; then
                print_message $RED "错误: 请提供要解密的文本"
                exit 1
            fi
            decrypt_string "$1"
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            print_message $RED "未知命令: $command"
            show_help
            exit 1
            ;;
    esac
}

main "$@"