#!/bin/bash

# 版本定义
FRP_VERSION="0.51.3"
CONTROLLER_VERSION="0.0.3"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 输出彩色信息
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }

# 检测系统架构
detect_arch() {
    local arch
    case $(uname -m) in
        x86_64|amd64)
            arch="amd64"
            ;;
        i386|i686)
            arch="386"
            ;;
        armv7l|armv6l)
            arch="arm"
            ;;
        aarch64|arm64)
            arch="arm64"
            ;;
        mips)
            arch="mips"
            ;;
        mips64)
            arch="mips64"
            ;;
        mips64le)
            arch="mips64le"
            ;;
        mipsle)
            arch="mipsle"
            ;;
        riscv64)
            arch="riscv64"
            ;;
        *)
            error "不支持的架构: $(uname -m)"
            exit 1
            ;;
    esac
    echo $arch
}

# 检测操作系统
detect_os() {
    local os
    case $(uname -s) in
        Linux)
            os="linux"
            ;;
        Darwin)
            os="darwin"
            ;;
        FreeBSD)
            os="freebsd"
            ;;
        *)
            error "不支持的操作系统: $(uname -s)"
            exit 1
            ;;
    esac
    echo $os
}

# 下载文件
download_file() {
    local url=$1
    local output=$2
    
    if command -v wget >/dev/null 2>&1; then
        wget -O "$output" "$url"
    elif command -v curl >/dev/null 2>&1; then
        curl -L -o "$output" "$url"
    else
        error "请安装 wget 或 curl"
        exit 1
    fi
}

# 解压文件
extract_file() {
    local file=$1
    local target_dir=$2
    
    mkdir -p "$target_dir"
    
    case "$file" in
        *.tar.gz)
            tar -xzf "$file" -C "$target_dir" --strip-components=1
            ;;
        *.zip)
            if command -v unzip >/dev/null 2>&1; then
                unzip -q "$file" -d "$target_dir"
                # 移动文件到目标目录
                find "$target_dir" -name "frps*" -exec mv {} "$target_dir/" \; 2>/dev/null || true
            else
                error "请安装 unzip"
                exit 1
            fi
            ;;
        *)
            error "不支持的压缩格式: $file"
            exit 1
            ;;
    esac
}

# 创建目录结构
create_directories() {
    info "创建目录结构..."
    mkdir -p /opt/lcf/frps
    mkdir -p /opt/lcf/opengfw
}

# 安装 FRPS
install_frps() {
    info "开始安装 FRPS..."
    
    local os=$(detect_os)
    local arch=$(detect_arch)
    
    # Windows 系统使用 zip，其他使用 tar.gz
    local ext="tar.gz"
    if [ "$os" = "windows" ]; then
        ext="zip"
    fi
    
    local filename="frp_LoCyanFrp-${FRP_VERSION}_${os}_${arch}.${ext}"
    local url="https://mirrors.locyan.cn/github-release/LoCyan-Team/LoCyanFrpPureApp/LatestRelease/${filename}"
    local temp_file="/tmp/${filename}"
    
    info "下载 FRPS: $url"
    download_file "$url" "$temp_file"
    
    info "解压 FRPS..."
    extract_file "$temp_file" "/opt/lcf/frps"
    
    # 设置执行权限
    if [ "$os" != "windows" ]; then
        chmod +x /opt/lcf/frps/frps
    fi
    
    rm -f "$temp_file"
}

# 配置 FRPS
configure_frps() {
    info "配置 FRPS..."
    
    # 获取用户输入
    read -p "请输入 dashboard 密码 (默认: Locyan666): " dashboard_pwd
    dashboard_pwd=${dashboard_pwd:-Locyan666}
    
    read -p "请输入节点 ID (默认: 55): " node_id
    node_id=${node_id:-55}
    
    # 创建 frps.ini
    cat > /opt/lcf/frps/frps.ini << EOF
[common]
bind_addr = 0.0.0.0
bind_port = 2333
kcp_bind_port = 2333
dashboard_port = 8233
dashboard_user = admin
dashboard_pwd = ${dashboard_pwd}
vhost_http_port = 80
vhost_https_port = 443
#log_file = ./frps.log
token = LoCyanToken
bind_udp_port = 7001

max_pool_count = 10000
tcp_mux = true
authentication_timeout = 0
log_level = debug
log_max_days = 3

api_enable = true
api_token = LoCyanToken
node_id = ${node_id}
EOF
    
    # 保存配置供后续使用
    echo "$dashboard_pwd" > /tmp/frps_dashboard_pwd
    echo "$node_id" > /tmp/frps_node_id
}

# 创建 FRPS 服务
create_frps_service() {
    info "创建 FRPS 服务..."
    
    cat > /etc/systemd/system/lcf-frps.service << EOF
[Unit]
Description=LoCyanFrp Server
After=network.target

[Service]
WorkingDirectory=/opt/lcf/frps
ExecStart=/opt/lcf/frps/frps -c frps.ini
Restart=always

[Install]
WantedBy=multi-user.target
EOF
}

# 安装控制器
install_controller() {
    info "开始安装控制器..."
    
    local arch=$(detect_arch)
    local filename="controller_${CONTROLLER_VERSION}_linux_${arch}.tar.gz"
    local url="https://hub.locyan.cloud/https://github.com/LoCyan-Team/LoCyanFrpController/releases/download/v${CONTROLLER_VERSION}/${filename}"
    local temp_file="/tmp/${filename}"
    
    info "下载控制器: $url"
    download_file "$url" "$temp_file"
    
    info "解压控制器..."
    extract_file "$temp_file" "/opt/lcf"
    
    # 设置执行权限
    chmod +x /opt/lcf/controller
    
    rm -f "$temp_file"
}

# 配置控制器
configure_controller() {
    info "配置控制器..."
    
    local dashboard_pwd=$(cat /tmp/frps_dashboard_pwd)
    local node_id=$(cat /tmp/frps_node_id)
    
    read -p "请输入监控节点名称: " monitor_name
    read -p "请输入监控鉴权密码: " monitor_pwd
    
    # 询问是否是中国大陆节点
    read -p "是否是中国大陆节点? (y/N): " is_china
    is_china=${is_china:-n}
    
    local ruleset_content
    if [ "$is_china" = "y" ] || [ "$is_china" = "Y" ]; then
        read -p "请输入服务器IP地址: " server_ip
        ruleset_content=$(cat << EOF
- name: Block ShadowSocks and Vmess
  action: block
  log: true
  expr: fet != nil && fet.yes && (port.dst >= 10000) && (port.dst <= 65535)

- name: Block Trojan
  action: block
  log: true
  expr: trojan != nil && trojan.yes && (port.dst >= 10000) && (port.dst <= 65535)

- name: Block Socks
  action: block
  log: true
  expr: socks != nil && socks.yes && (port.dst >= 10000) && (port.dst <= 65535)

- name: Block OpenVPN
  action: block
  log: true
  expr: openvpn != nil && openvpn.rx_pkt_cnt + openvpn.tx_pkt_cnt > 50 && (port.dst >= 10000) && (port.dst <= 65535)

- name: Block Non-standard HTTP Traffic
  action: drop
  log: true
  expr: http != nil && ip?.dst == '${server_ip}' && (port.dst >= 10000) && (port.dst <= 65535)
EOF
)
    else
        ruleset_content=$(cat << EOF
- name: Block ShadowSocks and Vmess
  action: block
  log: true
  expr: fet != nil && fet.yes && (port.dst >= 10000) && (port.dst <= 65535)

- name: Block Trojan
  action: block
  log: true
  expr: trojan != nil && trojan.yes && (port.dst >= 10000) && (port.dst <= 65535)

- name: Block Socks
  action: block
  log: true
  expr: socks != nil && socks.yes && (port.dst >= 10000) && (port.dst <= 65535)

- name: Block OpenVPN
  action: block
  log: true
  expr: openvpn != nil && openvpn.rx_pkt_cnt + openvpn.tx_pkt_cnt > 50 && (port.dst >= 10000) && (port.dst <= 65535)

#- name: Block Non-standard HTTP Traffic
#  action: drop
#  log: true
#  expr: http != nil && ip?.dst == '%IP%' && (port.dst >= 10000) && (port.dst <= 65535)
EOF
)
    fi
    
    # 创建 config.ini
    cat > /opt/lcf/config.ini << EOF
[common]
enable = false
send_duration = 10
addr = wss://api.locyanfrp.cn/frp/ws
node_id = ${node_id}
node_api_key = Locyan666

[frps]
username = admin
password = ${dashboard_pwd}
admin_api_host = localhost
admin_api_port = 8233

[opengfw]
enable = true
config_file = opengfw/config.yml
ruleset_file = opengfw/ruleset.yml

[monitor]
name = "${monitor_name}"
enable = true
addr = wss://status.api.locyanfrp.cn/monitor
network_device = eth0
auth_secret = ${monitor_pwd}
EOF
    
    # 创建 opengfw 配置文件
    cat > /opt/lcf/opengfw/config.yml << EOF
io:
  queueSize: 1024
  local: true

workers:
  count: 4
  queueSize: 64
  tcpMaxBufferedPagesTotal: 65536
  tcpMaxBufferedPagesPerConn: 16
  tcpTimeout: 10m
  udpMaxStreams: 4096

# The path to load specific local geoip/geosite db files.
# If not set, they will be automatically downloaded from https://github.com/Loyalsoldier/v2ray-rules-dat
# ruleset:
#   geoip: geoip.dat
#   geosite: geosite.dat

#replay:
#  realtime: false
EOF
    
    # 创建 ruleset.yml
    echo "$ruleset_content" > /opt/lcf/opengfw/ruleset.yml
}

# 创建控制器服务
create_controller_service() {
    info "创建控制器服务..."
    
    cat > /etc/systemd/system/lcf-controller.service << EOF
[Unit]
Description=LoCyanFrp Controller
After=network.target

[Service]
WorkingDirectory=/opt/lcf
ExecStart=/opt/lcf/controller
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
EOF
}

# 启动服务
start_services() {
    info "启动服务..."
    
    systemctl daemon-reload
    
    systemctl enable lcf-frps
    systemctl start lcf-frps
    
    systemctl enable lcf-controller
    systemctl start lcf-controller
    
    info "服务启动完成!"
    info "FRPS 状态: systemctl status lcf-frps"
    info "控制器状态: systemctl status lcf-controller"
    info "FRPS 面板: http://服务器IP:8233"
    info "用户名: admin"
    info "密码: $(cat /tmp/frps_dashboard_pwd)"
}

# 清理临时文件
cleanup() {
    rm -f /tmp/frps_dashboard_pwd
    rm -f /tmp/frps_node_id
}

# 主函数
main() {
    info "开始安装 LoCyanFrp..."
    
    # 检查 root 权限
    if [ "$EUID" -ne 0 ]; then
        error "请使用 root 权限运行此脚本"
        exit 1
    fi
    
    create_directories
    install_frps
    configure_frps
    create_frps_service
    install_controller
    configure_controller
    create_controller_service
    start_services
    cleanup
    
    info "LoCyanFrp 安装完成!"
}

# 执行主函数
main "$@"
