#!/bin/bash
# Naixi System Manager v2.0
# Usage: naixi <command> [args]

NAIXI_VERSION="2.0.0"
NAIXI_DIR="/etc/log/naixi"
PMD_DB_DIR="/etc/log/packages/db"
PMD_PKG_DIR="/etc/log/packages"
DL_BASE="https://dl.naixi.net/ikuai-plugin"

# 已知插件密钥表
declare -A SECRET_KEYS=(
    [docker]="354a738f7b2756a848f3b8de541ec57"
    [docker-bin]="354a738f7b2756a848f3b8de541ec58"
    [shell]="70946f9965a3c140b28e36a82ed148b"
    [ik_host]="jJ9FzkgwUm6bL3dG"
    [pmd]="challstr@holly~"
)
PMD_DB_KEY="ikupdat-d~#-"

log() { echo "[naixi] $*"; }
err() { echo "[naixi] ERROR: $*" >&2; }

cmd_version() {
    echo "Naixi System Manager v${NAIXI_VERSION}"
    echo "  Cloud: level $(cat ${NAIXI_DIR}/cloud_level 2>/dev/null || echo 1)"
    echo "  IPv6: $(cat /etc/mnt/.ipv6_multi 2>/dev/null | head -1 || echo 'N/A')"
    echo "  SSH: $(netstat -tlnp 2>/dev/null | grep -q ':22 ' && echo 'ON' || echo 'OFF')"
}

cmd_status() {
    echo "=== Naixi System Manager v${NAIXI_VERSION} ==="
    echo ""
    echo "System:"
    echo "  Uptime: $(uptime | awk -F'up ' '{print $2}' | awk -F',' '{print $1}')"
    echo "  Memory: $(free -m 2>/dev/null | awk '/Mem/{printf "%dMB/%dMB (%.0f%%)", $3, $2, $3/$2*100}')"
    echo "  Disk:   $(df -h /etc/log 2>/dev/null | awk 'NR==2{printf "%s/%s (%s)", $3, $2, $5}')"
    echo ""
    echo "Services:"
    echo "  Cloud: level $(cat ${NAIXI_DIR}/cloud_level 2>/dev/null || echo 1)"
    echo "  IPv6:  $([ -f /etc/mnt/.ipv6_multi ] && echo 'enabled' || echo 'disabled')"
    echo "  SSH:   $(netstat -tlnp 2>/dev/null | grep -q ':22 ' && echo 'running' || echo 'stopped')"
    echo ""
    echo "Plugins:"
    if [ -d /tmp/ikpkg ]; then
        for d in /tmp/ikpkg/*/; do
            [ -f "${d}version" ] && echo "  $(basename $d): v$(cat ${d}version)"
        done
    else
        echo "  (none)"
    fi
}

cmd_cloud() {
    local level="${1:-}"
    if [ -z "$level" ]; then
        echo "Cloud control level: $(cat ${NAIXI_DIR}/cloud_level 2>/dev/null || echo 1)"
        echo "  0 = off (only hook sysupgrade)"
        echo "  1 = default (block cloud + kill update_hosts)"
        echo "  2 = strict (block all ikuai8.com)"
        return
    fi
    case "$level" in
        0|1|2)
            mkdir -p ${NAIXI_DIR}
            echo "$level" > ${NAIXI_DIR}/cloud_level
            log "Cloud control set to level $level"
            # 立即应用
            if [ "$level" -ge 1 ]; then
                for h in genuine coll iapi yun 302 audit routers youyu.api; do
                    grep -q "${h}.ikuai8.com" /etc/hosts || echo "127.0.0.1 ${h}.ikuai8.com" >> /etc/hosts
                done
                killall update_hosts.sh 2>/dev/null
            fi
            if [ "$level" -ge 2 ]; then
                for h in dpi download www; do
                    grep -q "${h}.ikuai8.com" /etc/hosts || echo "127.0.0.1 ${h}.ikuai8.com" >> /etc/hosts
                done
            fi
            log "Applied cloud level $level"
            ;;
        *) err "Invalid level: $level (use 0/1/2)" ;;
    esac
}

cmd_ipv6() {
    if [ -f /etc/mnt/.ipv6_multi ]; then
        echo "IPv6 status: $(cat /etc/mnt/.ipv6_multi)"
    else
        echo "IPv6: not configured"
    fi
    echo ""
    echo "To force enable:"
    echo "  naixi ipv6 enable [num]"
}

cmd_ipv6_enable() {
    local num="${1:-9999}"
    echo "expires=0 num=${num} enterprise=1" > /etc/mnt/.ipv6_multi
    log "IPv6 enabled: num=${num}, never expires"
}

cmd_ssh() {
    case "${1:-}" in
        on)
            /usr/sbin/dropbear -p 22 2>/dev/null
            log "SSH started on port 22"
            ;;
        off)
            killall dropbear 2>/dev/null
            log "SSH stopped"
            ;;
        *)
            echo "SSH: $(netstat -tlnp 2>/dev/null | grep -q ':22 ' && echo 'running' || echo 'stopped')"
            echo "  naixi ssh on|off"
            ;;
    esac
}

cmd_passwd() {
    local pw="${1:-}"
    if [ -z "$pw" ]; then
        echo "Usage: naixi passwd <password>"
        return 1
    fi
    echo "root:${pw}" | chpasswd 2>/dev/null
    echo "sshd:${pw}" | chpasswd 2>/dev/null
    log "Password updated for root and sshd"
}

cmd_install() {
    local src="${1:-}"
    if [ -z "$src" ]; then
        echo "Usage: naixi install <file.tar.gz|url>"
        echo "  naixi install docker.tar.gz"
        echo "  naixi install ${DL_BASE}/docker.tar.gz"
        return 1
    fi

    local tmpfile="/tmp/naixi_install_pkg.tar.gz"

    # 下载或复制
    if echo "$src" | grep -q "^http"; then
        log "Downloading $src ..."
        wget -q -O "$tmpfile" "$src" || { err "Download failed"; return 1; }
    elif [ -f "$src" ]; then
        cp "$src" "$tmpfile"
    else
        err "File not found: $src"; return 1
    fi

    # 检测插件名 (从tar.gz中提取)
    local name=""
    name=$(tar tzf "$tmpfile" 2>/dev/null | head -1 | cut -d'/' -f1)
    if [ -z "$name" ]; then
        err "Cannot detect plugin name from archive"
        rm -f "$tmpfile"
        return 1
    fi
    log "Plugin: $name"

    # 查找密钥
    local key="${SECRET_KEYS[$name]:-}"
    if [ -z "$key" ]; then
        # 尝试用pmd默认密钥
        key="${SECRET_KEYS[pmd]}"
        log "Using default pmd key for $name"
    fi

    # 加密 tar.gz → .bin.pkg (openssl)
    log "Encrypting $name.bin.pkg ..."
    openssl enc -aes-256-cbc -salt -in "$tmpfile" -out "${PMD_PKG_DIR}/${name}.bin.pkg" -k "$key" -md md5 2>/dev/null
    if [ $? -ne 0 ]; then
        err "Encryption failed"
        rm -f "$tmpfile"
        return 1
    fi

    # 注入pmd数据库
    log "Injecting into PMD database ..."
    _pmd_inject "$name" "1.0.0" "$key"

    # 重启pmd
    log "Restarting pmd ..."
    killall pmd 2>/dev/null
    rm -rf /tmp/packages 2>/dev/null
    sleep 1
    pmd &
    sleep 5

    # 检查安装结果
    if [ -f "/tmp/ikpkg/${name}/version" ]; then
        log "✅ $name installed successfully! v$(cat /tmp/ikpkg/${name}/version)"
    else
        log "⏳ $name installing... (check later with: naixi plugin list)"
    fi

    rm -f "$tmpfile"
}

_pmd_inject() {
    local name="$1" version="$2" secret="$3"
    local db_file="${PMD_DB_DIR}/.__DB.3.x86_64"

    mkdir -p "${PMD_DB_DIR}"

    # 如果已有db，解密→追加→重加密
    # 简化实现：直接生成新的JSON
    local json="[{\"name\":\"${name}\",\"version\":\"${version}\",\"secret_key\":\"${secret}\",\"download\":\"\",\"md5\":\"\",\"arch\":\"x86_64\"}]"

    # 如果已有db且能解密，合并
    if [ -f "$db_file" ]; then
        local existing
        existing=$(openssl enc -aes-256-cbc -d -in "$db_file" -k "$PMD_DB_KEY" -md md5 2>/dev/null)
        if [ $? -eq 0 ] && echo "$existing" | python3 -c "import sys,json; json.load(sys.stdin)" 2>/dev/null; then
            # 用python合并JSON
            json=$(echo "$existing" | python3 -c "
import sys, json
db = json.load(sys.stdin)
name = '${name}'
found = False
for i, p in enumerate(db):
    if p.get('name') == name:
        db[i]['secret_key'] = '${secret}'
        db[i]['version'] = '${version}'
        found = True
        break
if not found:
    db.append({'name':name,'version':'${version}','secret_key':'${secret}','download':'','md5':'','arch':'x86_64'})
print(json.dumps(db))
" 2>/dev/null)
        fi
    fi

    echo -n "$json" | openssl enc -aes-256-cbc -salt -out "$db_file" -k "$PMD_DB_KEY" -md md5 2>/dev/null
    log "PMD database updated: $name"
}

cmd_uninstall() {
    local name="${1:-}"
    if [ -z "$name" ]; then
        echo "Usage: naixi uninstall <plugin>"
        return 1
    fi

    # 停止服务
    [ -f "/tmp/ikpkg/${name}/script/${name}.sh" ] && /tmp/ikpkg/${name}/script/${name}.sh stop 2>/dev/null

    # 删除pkg
    rm -f "${PMD_PKG_DIR}/${name}.bin.pkg"
    rm -rf "/tmp/ikpkg/${name}"

    # 从pmd db中移除
    local db_file="${PMD_DB_DIR}/.__DB.3.x86_64"
    if [ -f "$db_file" ]; then
        local existing
        existing=$(openssl enc -aes-256-cbc -d -in "$db_file" -k "$PMD_DB_KEY" -md md5 2>/dev/null)
        if [ $? -eq 0 ]; then
            local new_json
            new_json=$(echo "$existing" | python3 -c "
import sys, json
db = json.load(sys.stdin)
db = [p for p in db if p.get('name') != '${name}']
print(json.dumps(db))
" 2>/dev/null)
            echo -n "$new_json" | openssl enc -aes-256-cbc -salt -out "$db_file" -k "$PMD_DB_KEY" -md md5 2>/dev/null
        fi
    fi

    killall pmd 2>/dev/null
    sleep 1
    pmd &

    log "✅ $name uninstalled"
}

cmd_plugin_list() {
    echo "=== Installed Plugins ==="
    if [ -d /tmp/ikpkg ]; then
        for d in /tmp/ikpkg/*/; do
            local n=$(basename "$d")
            local v="unknown"
            [ -f "${d}version" ] && v=$(cat "${d}version")
            local status="running"
            echo "  ${n}: v${v} [${status}]"
        done
    else
        echo "  (none installed)"
    fi
    echo ""
    echo "Available:"
    echo "  naixi install ${DL_BASE}/docker.tar.gz"
    echo "  naixi install ${DL_BASE}/shell.tar.gz"
}

cmd_plugin_export() {
    local name="${1:-}"
    if [ -z "$name" ]; then
        echo "Usage: naixi export <plugin> [output.tar.gz]"
        return 1
    fi
    local pkg="${PMD_PKG_DIR}/${name}.bin.pkg"
    local key="${SECRET_KEYS[$name]:-${SECRET_KEYS[pmd]}}"
    local out="${2:-/tmp/${name}.tar.gz}"

    if [ ! -f "$pkg" ]; then
        err "Package not found: $pkg"
        return 1
    fi

    openssl enc -aes-256-cbc -d -in "$pkg" -out "$out" -k "$key" -md md5 2>/dev/null
    if [ $? -eq 0 ]; then
        log "✅ Exported to $out ($(du -h "$out" | cut -f1))"
    else
        err "Decryption failed"
    fi
}

cmd_diag() {
    echo "=== Naixi Diagnostics ==="
    echo ""
    echo "Network:"
    ping -c1 -W2 8.8.8.8 >/dev/null 2>&1 && echo "  Internet: ✅" || echo "  Internet: ❌"
    ping -c1 -W2 dl.naixi.net >/dev/null 2>&1 && echo "  dl.naixi.net: ✅" || echo "  dl.naixi.net: ❌"
    echo ""
    echo "Disk:"
    df -h /etc/log 2>/dev/null | awk 'NR==2{printf "  /etc/log: %s/%s (%s used)\n", $3, $2, $5}'
    echo ""
    echo "Processes:"
    for p in pmd ik_core httpd dropbear dockerd; do
        pidof $p >/dev/null 2>&1 && echo "  $p: ✅ running" || echo "  $p: ❌ stopped"
    done
    echo ""
    echo "Cloud:"
    echo "  Level: $(cat ${NAIXI_DIR}/cloud_level 2>/dev/null || echo 1)"
    grep -q "genuine.ikuai8.com" /etc/hosts 2>/dev/null && echo "  Hosts blocked: ✅" || echo "  Hosts blocked: ❌"
}

cmd_help() {
    cat << EOF
Naixi System Manager v${NAIXI_VERSION}

System:
  naixi status              System overview
  naixi cloud [0|1|2]       Cloud control level
  naixi ipv6 [enable N]     IPv6 management
  naixi ssh [on|off]        SSH control
  naixi passwd <pw>         Change SSH password
  naixi diag                Diagnostics

Plugins:
  naixi install <file|url>  Install plugin (→ pmd)
  naixi uninstall <name>    Remove plugin
  naixi plugin list         List installed plugins
  naixi export <name>       Export plugin as tar.gz

Info:
  naixi version             Version info
  naixi help                This help
EOF
}

# 主入口
case "${1:-}" in
    status)     cmd_status ;;
    version|-v) cmd_version ;;
    cloud)      cmd_cloud "$2" ;;
    ipv6)
        case "${2:-}" in
            enable) cmd_ipv6_enable "$3" ;;
            *)      cmd_ipv6 ;;
        esac ;;
    ssh)        cmd_ssh "$2" ;;
    passwd)     cmd_passwd "$2" ;;
    install)    cmd_install "$2" ;;
    uninstall)  cmd_uninstall "$2" ;;
    plugin)
        case "${2:-}" in
            list) cmd_plugin_list ;;
            *)    cmd_plugin_list ;;
        esac ;;
    export)     cmd_plugin_export "$2" "$3" ;;
    diag)       cmd_diag ;;
    help|--help|-h|"") cmd_help ;;
    *)          err "Unknown command: $1"; cmd_help ;;
esac
