#!/usr/bin/env bash

scriptdir=$(dirname $(realpath $0))
tempdir=$(mktemp -d)

if [[ $(sudo id -u) -ne 0 ]]; then
    echo "Please get sudo access first."
    exit 1
fi

# ============================================================

. $scriptdir/configure_user.sh

# ============================================================

configure_tuna() {
    [ $offline -eq 1 ] && return
    [ $abroad -eq 1 ] && return

    if confirm_action "要切换 Tuna 源吗？" "N"; then
        python3 $scriptdir/files/oh-my-tuna.py
        # 如果 uid 不为 0 则 sudo 再跑一次
        if [[ $EUID -ne 0 ]]; then
            sudo python3 $scriptdir/files/oh-my-tuna.py
        fi
    fi
}

configure_upgrade() {
    [ $offline -eq 1 ] && return

    if [ "$(uname)" = "Darwin" ]; then
        # macOS 系统使用 brew
        if confirm_action "要运行 brew upgrade 吗？" "N"; then
            brew update
            brew upgrade
            brew cleanup
        fi
    else
        # 其他系统使用 apt
        if confirm_action "要运行 apt-get upgrade 吗？" "N"; then
            sudo apt-get update
            sudo apt-get upgrade -y
            sudo apt-get autoremove -y
        fi
    fi
}

configure_install_basic() {
    if [ "$(uname)" = "Darwin" ]; then
        [ "$1" != "noupdate" ] && brew update
        brew install tmux htop
    else
        [ "$1" != "noupdate" ] && sudo apt-get update
        sudo apt-get install tmux git curl htop net-tools tar unzip -y
    fi
    pip3 install trash-cli --break-system-packages
}

configure_install_useful() {
    if [ "$(uname)" = "Darwin" ]; then
        [ "$1" != "noupdate" ] && brew update
        brew install hexyl bat tree p7zip
        brew install mtr
    else
        [ "$1" != "noupdate" ] && sudo apt-get update
        sudo apt-get install hexyl bat tree fd-find fzf -y
        # 原来有 tcptraceroute 的，用 mtr 替代
        sudo apt-get install hping3 mtr -y
    fi
    pip3 install ipython tcpp --break-system-packages
}

configure_install_new() {
    if [ "$(uname)" = "Darwin" ]; then
        [ "$1" != "noupdate" ] && brew update
        brew install pigz
    else
        [ "$1" != "noupdate" ] && sudo apt-get update
        sudo apt-get install pigz -y
    fi
    pip3 install speedtest-cli --break-system-packages
}

configure_install_old() {
    if [ "$(uname)" = "Darwin" ]; then
        [ "$1" != "noupdate" ] && brew update
        brew install neofetch cloc
    else
        [ "$1" != "noupdate" ] && sudo apt-get update
        sudo apt-get install neofetch cloc -y
    fi
}

configure_install_eza() {
    if [ "$(uname)" = "Darwin" ]; then
        brew install eza
    elif [[ $(uname -m) != "x86_64" && $(uname -m) != "aarch64" ]]; then
        echo "eza is not supported on $(uname -m)."
    elif ! command_exists eza; then
        if [[ "$(lsb_release -is)" == "Ubuntu" && ("$(lsb_release -rs)" == "24.04" || "$(lsb_release -rs)" > "24.04") ]]; then
            sudo apt-get install eza -y
        else
            unzip $scriptdir/files/eza_$(uname -m)-unknown-linux-musl.zip -d $tempdir/eza
            sudo cp $tempdir/eza/eza /usr/local/bin/
            rm $tempdir/eza -r
        fi
    fi
}

configure_install() {
    if [ "$(uname)" = "Darwin" ]; then
        # macOS 系统使用 brew
        if confirm_action "要运行 brew/pip3 install 吗？" "N"; then
            brew update
        else
            return
        fi
    else
        if confirm_action "要运行 apt/pip3 install 吗？" "N"; then
            sudo apt-get update
        else
            return
        fi
    fi
    configure_install_basic noupdate
    configure_install_useful noupdate
    configure_install_new noupdate
    configure_install_eza noupdate
}

configure_nano() {
    [ -f ~/.nanorc ] && return

    if confirm_action "要配置 nano 吗？" "Y"; then
        pkg_install nano
        cp $scriptdir/files/.nanorc ~/.nanorc
    fi
}

configure_vim() {
    [ -f ~/.vimrc ] && return

    if confirm_action "要配置 vim 吗？" "Y"; then
        pkg_install vim
        cp $scriptdir/files/.vimrc ~/.vimrc
    fi
}

configure_zsh() {
    [ -d ~/.oh-my-zsh ] && return
    [ $offline -eq 1 ] && return

    if confirm_action "要配置 zsh 吗？" "Y"; then
        pkg_install zsh

        rm ~/.oh-my-zsh -r
        git_clone ohmyzsh/ohmyzsh ~/.oh-my-zsh
        RUNZSH=no ZSH=~/.oh-my-zsh $scriptdir/files/install-ohmyzsh.sh

        git_clone zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
        git_clone zsh-users/zsh-syntax-highlighting ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting
        git_clone paulirish/git-open ~/.oh-my-zsh/custom/plugins/git-open --norecursive
        pkg_install autojump

        if ! grep -Fxq "source ~/.oh-my-zsh/custom/00-init.zsh" ~/.zshrc; then
            local zshrc="$HOME/.zshrc"
            local search_line="source \$ZSH/oh-my-zsh.sh"
            local add_line="source ~/.oh-my-zsh/custom/00-init.zsh"

            if [ "$(uname)" = "Darwin" ]; then
                # macOS
                awk -v search="$search_line" -v add="$add_line" '{
                    if (index($0, search) > 0) print add
                    print $0
                }' "$zshrc" >~/.zshrc.temp && mv ~/.zshrc.temp "$zshrc"
            else
                # Linux
                sed -i "\|${search_line}|i ${add_line}" "$zshrc"
            fi
        fi

        # 如果 ~/.zshrc 里面没有 source ~/.zsh_user 则添加
        if ! grep -qx "source ~/.zsh_user" ~/.zshrc; then
            if [ "$(uname)" = "Darwin" ]; then
                # macOS
                printf "\nsource ~/.zsh_user\n" >> ~/.zshrc
            else
                # Linux
                sed -i '$a source ~/.zsh_user' ~/.zshrc
            fi
        fi

        # 如果 ~/.zshrc 里面没有 conda initialize 则运行 mamba init zsh
        if ! grep -q "conda initialize" ~/.zshrc; then
            if [ -d ~/.miniconda3 ]; then
                ~/.miniconda3/bin/mamba init zsh
            elif [ -d ~/.miniforge3 ]; then
                ~/.miniforge3/bin/mamba init zsh
            fi
        fi

        cp $scriptdir/files/zsh/.zsh_user ~/.zsh_user
        cp $scriptdir/files/zsh/00-init.zsh ~/.oh-my-zsh/custom/
        cp $scriptdir/files/zsh/10-theme.zsh ~/.oh-my-zsh/custom/
        cp $scriptdir/files/zsh/20-function.zsh ~/.oh-my-zsh/custom/
        cp $scriptdir/files/zsh/50-env.zsh ~/.oh-my-zsh/custom/
        cp $scriptdir/files/zsh/51-alias.zsh ~/.oh-my-zsh/custom/
        cp $scriptdir/files/zsh/90-other.zsh ~/.oh-my-zsh/custom/
        cp $scriptdir/files/zsh/ys-simple.zsh-theme ~/.oh-my-zsh/custom/themes/

        [ $abroad -eq 1 ] && return
        cp $scriptdir/files/zsh/80-proxy.zsh ~/.oh-my-zsh/custom/
    fi
}

configure_tmux() {
    [ -f ~/.tmux.conf ] && return
    [ $offline -eq 1 ] && return

    if confirm_action "要配置 tmux 吗？" "Y"; then
        sudo apt-get install tmux -y

        rm ~/.tmux -r
        git_clone tmux-plugins/tpm ~/.tmux/plugins/tpm --norecursive
        git_clone tmux-plugins/tmux-sensible ~/.tmux/plugins/tmux-sensible
        git_clone tmux-plugins/tmux-yank ~/.tmux/plugins/tmux-yank
        git_clone tmux-plugins/tmux-prefix-highlight ~/.tmux/plugins/tmux-prefix-highlight
        git_clone seebi/tmux-colors-solarized ~/.tmux/plugins/tmux-colors-solarized

        cp $scriptdir/files/.tmux.conf ~/.tmux.conf
        [ "$(uname)" = "Darwin" ] && return
        sudo apt-get install xsel -y # 能够让 tmux 剪切板与 terminal 同步
    fi
}

configure_docker() {
    command_exists docker && return
    [ $offline -eq 1 ] && return
    [ "$(uname)" = "Darwin" ] && return

    if confirm_action "要安装 docker 吗？" "N"; then
        # 卸载旧版本
        sudo apt-get remove docker docker-engine docker.io
        sudo apt-get update
        sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release -y
        # 检查系统架构是否为 x86_64
        if [[ $(uname -m) != "x86_64" ]]; then
            echo "Docker is only supported on amd64 architecture."
            return
        fi
        # 添加软件源的 GPG 密钥，并向 sources.list 中添加 Docker 软件源
        if [ $abroad -eq 1 ]; then
            curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/docker-archive-keyring.gpg >/dev/null
            sudo rm -f /etc/apt/sources.list.d/docker.list
            sed "s|__CODENAME__|$(lsb_release -cs)|g" "$scriptdir/files/sources.list/docker-abroad.sources" | sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null
        else
            curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/docker-archive-keyring.gpg >/dev/null
            sudo rm -f /etc/apt/sources.list.d/docker.list
            sed "s|__CODENAME__|$(lsb_release -cs)|g" "$scriptdir/files/sources.list/docker-internal.sources" | sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null
        fi
        sudo apt-get update
        sudo apt-get install docker-ce docker-ce-cli containerd.io -y
        sudo systemctl enable docker
        sudo systemctl start docker

        # 安装 docker-compose-plugin
        sudo apt-get install docker-compose-plugin -y
        # 安装 docker-compose
        latest_version=$(curl -s "https://api.github.com/repos/docker/compose/releases/latest" | grep -o '"tag_name": ".*"' | cut -d'"' -f4)
        if [ -z "$latest_version" ]; then
            latest_version="v2.27.0"
        fi
        echo "Latest version of docker-compose is $latest_version"
        sudo curl -L "$github/docker/compose/releases/download/$latest_version/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
        sudo chmod +x /usr/local/bin/docker-compose

        # 如果 user 不是 root 的话，还得顺便配置一下 docker rootless
        if [[ $EUID -ne 0 ]]; then
            mkdir -p ~/.config/docker
            if [ $abroad -eq 1 ]; then
                cp $scriptdir/files/docker-rootless-daemon-aboard.json ~/.config/docker/daemon.json
            else
                cp $scriptdir/files/docker-rootless-daemon-internal.json ~/.config/docker/daemon.json
            fi

            sudo apt-get install -y uidmap
            /usr/bin/dockerd-rootless-setuptool.sh install

            # 设置 linger 为 on
            sudo loginctl enable-linger $USER
        fi
    fi
}

configure_yarn() {
    echo "Incomplete"
    return

    curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarn.gpg >/dev/null
    echo "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list >/dev/null
}

configure_mongodb() {
    echo "Incomplete"
    return

    version=7.0
    curl -fsSL https://pgp.mongodb.com/server-$version.asc | gpg --dearmor | sudo tee /usr/share/keyrings/mongodb-server-$version.gpg >/dev/null
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/mongodb-server-$version.gpg] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/$version multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-$version.list >/dev/null
}

configure_nginx() {
    [ $offline -eq 1 ] && return
    if [ ! -f /etc/apt/sources.list.d/nginx.sources ]; then
        curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx.gpg >/dev/null
        sudo rm -f /etc/apt/sources.list.d/nginx.list
        sed "s|__CODENAME__|$(lsb_release -cs)|g" "$scriptdir/files/sources.list/nginx.sources" | sudo tee /etc/apt/sources.list.d/nginx.sources >/dev/null
    fi
    if confirm_action "要安装 nginx 吗？" "Y"; then
        if command_exists nginx && ! confirm_action "检测到旧版 nginx 的存在 ($(nginx -v 2>&1))，是否继续安装？" "N"; then
            # sudo apt-get remove nginx -y
            return
        fi
        sudo apt-get update
        sudo apt-get install nginx -y
        echo "nginx 版本: $(nginx -v 2>&1)"
        echo "别忘了把 /etc/nginx/sites-enabled 中的配置文件移动到 /etc/nginx/conf.d 中"
    fi
}

configure_fail2ban() {
    [ -f /etc/fail2ban/jail.local ] && return
    [ $offline -eq 1 ] && return
    [ "$(uname)" = "Darwin" ] && return

    if confirm_action "要配置 fail2ban 吗？" "N"; then
        sudo apt-get install fail2ban -y
        sudo mkdir -p /etc/fail2ban
        sudo cp $scriptdir/files/jail.local /etc/fail2ban/jail.local
        sudo systemctl start fail2ban
        sudo systemctl enable fail2ban
        sudo fail2ban-client status sshd
    fi
}

configure_iptables() {
    [ $offline -eq 1 ] && return
    [ "$(uname)" = "Darwin" ] && return

    # 如果 ufw 是 active，就直接返回
    if command_exists ufw; then
        if sudo ufw status | grep -q "Status: active"; then
            echo "检测到 ufw 已启用，跳过 iptables 配置。"
            return
        fi
        if confirm_action "检测到 ufw 已存在，是否直接使用 ufw 进行管理，跳过 iptables" "Y"; then
            return
        fi
    fi

    if command_exists ifquery && systemctl is-active --quiet networking; then
        # ifupdown: /etc/network/if-pre-up.d/iptables-load
        [ -f /etc/network/if-pre-up.d/iptables-load ] && return
        if confirm_action "要配置 iptables 吗？" "N"; then
            sudo cp $scriptdir/files/iptables-load /etc/network/if-pre-up.d/iptables-load
            sudo chmod +x /etc/network/if-pre-up.d/iptables-load
            sudo sh /etc/network/if-pre-up.d/iptables-load
        fi
    else
        # systemd: /etc/network/iptables-load
        [ -f /etc/network/iptables-load ] && return
        if confirm_action "要配置 iptables 吗？" "N"; then
            if [ -f /etc/network/if-pre-up.d/iptables-load ]; then
                sudo mv /etc/network/if-pre-up.d/iptables-load /etc/network/iptables-load
            else
                sudo cp $scriptdir/files/iptables-load /etc/network/iptables-load
                sudo chmod +x /etc/network/iptables-load
                sudo sh /etc/network/iptables-load
            fi

            sudo cp $scriptdir/files/iptables-load.service /etc/systemd/system/iptables-load.service
            sudo chmod +x /etc/systemd/system/iptables-load.service
            sudo systemctl daemon-reload
            sudo systemctl start iptables-load.service
            sudo systemctl enable iptables-load.service
        fi
    fi
}

configure_ufw() {
    [ $offline -eq 1 ] && return
    [ "$(uname)" = "Darwin" ] && return
    ! command_exists ufw && return

    if sudo ufw status | grep -q "Status: inactive"; then
        return
    fi

    # 如果 ufw 没有被脚本初始化过
    if ! sudo ufw status verbose | grep -q "Initialized by lazy"; then
        if confirm_action "要配置 ufw 吗？" "N"; then
            # 默认拒绝所有入站连接
            sudo ufw default deny incoming
            sudo ufw default allow outgoing
            # 允许常用端口
            sudo ufw allow ssh comment 'SSH (Initialized by lazy)'
            sudo ufw allow http
            sudo ufw allow https
            sudo ufw allow 2263/tcp comment 'SSH'
            sudo ufw allow 9443/tcp comment 'gost-proxy'
            sudo ufw allow 6330/tcp comment 'node-exporter'
        fi
    fi
}

configure_zsh_prefix() {
    [ -f ~/.zsh_user ] || return

    if confirm_action "要修改 zsh 的 prefix 吗？" "N"; then
        read -p "zsh prefix: " new_prefix
        if [ "$(uname)" = "Darwin" ]; then
            # macOS
            sed -i '' "1s/.*/HOST=\"$new_prefix\"/" ~/.zsh_user
        else
            # Linux
            sed -i "1s/.*/HOST=\"$new_prefix\"/" ~/.zsh_user
        fi
    fi
}

configure_hostname() {
    if confirm_action "要修改 hostname 吗？" "N"; then
        read -p "hostname: " new_hostname
        echo $new_hostname | sudo tee /etc/hostname >/dev/null
    fi
}

configure_timedate() {
    [ "$(uname)" = "Darwin" ] && return
    [[ $(timedatectl | grep "Time zone" | awk '{print $3}') == "Asia/Shanghai" ]] && return

    if confirm_action "要修改 时区 吗？" "N"; then
        sudo timedatectl set-timezone Asia/Shanghai
    fi
}

configure_bootinfo() {
    [ -d /etc/update-motd.d/disable ] && return
    [ "$(uname)" = "Darwin" ] && return

    if confirm_action "要修改 启动信息 吗？" "Y"; then
        sudo mkdir /etc/update-motd.d/disable
        sudo mv /etc/update-motd.d/10-help-text /etc/update-motd.d/disable/
        sudo mv /etc/update-motd.d/50-motd-news /etc/update-motd.d/disable/
        # sudo mv /etc/update-motd.d/88-esm-announce /etc/update-motd.d/disable/
        if [ -d /usr/lib/python3/dist-packages/landscape/sysinfo ]; then
            sudo sed -i 's/"Network"/"Network_Simple"/g' /usr/lib/python3/dist-packages/landscape/sysinfo/deployment.py
            sudo cp $scriptdir/files/sysinfo_network_simple.py /usr/lib/python3/dist-packages/landscape/sysinfo/network_simple.py
        fi
    fi
}

configure_oomkiller() {
    [ -f /etc/default/earlyoom ] && return
    [ $offline -eq 1 ] && return
    [ "$(uname)" = "Darwin" ] && return

    if confirm_action "要启用 earlyoom 吗？" "Y"; then
        sudo apt-get install earlyoom -y
        sudo cp $scriptdir/files/earlyoom.conf /etc/default/earlyoom
        sudo systemctl restart earlyoom
    fi
}

configure_proxychains() {
    [ -f /etc/proxychains4.conf ] && return
    [ $offline -eq 1 ] && return
    [ "$(uname)" = "Darwin" ] && return

    if confirm_action "要配置 proxychains 吗？" "N"; then
        sudo apt-get install proxychains4 -y
        sudo cp $scriptdir/files/proxychains4.conf /etc/proxychains4.conf
    fi
}

configure_node_exporter() {
    [ -f /usr/local/bin/node_exporter ] && return
    [ $offline -eq 1 ] && return

    if confirm_action "要配置 Node Exporter 吗？" "N"; then
        latest_version=$(curl -s "https://api.github.com/repos/prometheus/node_exporter/releases/latest" | grep -o '"tag_name": ".*"' | cut -d'"' -f4)
        if [ -z "$latest_version" ]; then
            latest_version="v1.8.2"
        fi
        echo "Latest version of node-exporter is $latest_version"

        release="node_exporter-${latest_version#v}.$(uname -s)-$(dpkg --print-architecture).tar.gz"
        wget $github/prometheus/node_exporter/releases/download/$latest_version/$release -O $tempdir/node_exporter.tar.gz
        tar -xzf $tempdir/node_exporter.tar.gz -C $tempdir

        node_exporter_dir=$(find $tempdir -type d -name "node_exporter-*")

        sudo cp $node_exporter_dir/node_exporter /usr/local/bin/node_exporter
        sudo chmod +x /usr/local/bin/node_exporter
        rm $tempdir/node_exporter.tar.gz
        rm $node_exporter_dir -r

        # Generate a self-signed certificate
        # openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -keyout node_exporter.key -out node_exporter.crt
        #   -subj "/C=CN/ST=Beijing/L=Beijing/O=nano.ac/CN=localhost"
        #   -addext "subjectAltName=DNS:localhost,DNS:host.docker.internal,DNS:*.nano.ac,DNS:*.c-4.cc"

        if [ ! -d "/etc/node_exporter" ]; then
            sudo mkdir -p /etc/node_exporter
        fi
        sudo cp $scriptdir/files/node_exporter.yml /etc/node_exporter/config.yml
        sudo cp $scriptdir/files/node_exporter.crt /etc/node_exporter/cert.crt
        sudo chmod 644 /etc/node_exporter/cert.crt
        sudo cp $scriptdir/files/node_exporter.key /etc/node_exporter/cert.key
        sudo chmod 644 /etc/node_exporter/cert.key

        # Create a systemd service
        sudo cp $scriptdir/files/node_exporter.service /etc/systemd/system/node_exporter.service
        sudo chmod +x /etc/systemd/system/node_exporter.service
        sudo systemctl daemon-reload
        sudo systemctl start node_exporter
        sudo systemctl enable node_exporter
    fi
}

configure_nginx_log() {
    [ $offline -eq 1 ] && return
    [ "$(uname)" = "Darwin" ] && return
    ! command_exists nginx && return
    [ ! -f /etc/logrotate.d/nginx ] && return
    [ -z "$(grep 'daily' /etc/logrotate.d/nginx)" ] && return

    if confirm_action "要配置 nginx 日志轮转修改为每周吗？" "N"; then
        # 修改 /etc/logrotate.d/nginx 文件，替换 daily 为 weekly
        sudo sed -i 's/daily/weekly/' /etc/logrotate.d/nginx
        # 重新加载 logrotate 配置
        sudo logrotate -f /etc/logrotate.d/nginx
    fi
}

# configure_nodejs() {
#     [ -f /usr/local/bin/node ] && return
#     [ $offline -eq 1 ] && return

#     if confirm_action "要安装 nodejs 吗？" "Y"; then
#         local version="v20.10.0"
#         local tarname="node-$version-linux-x64"
#         wget https://nodejs.org/dist/$version/$tarname.tar.xz -O $tempdir/$tarname.tar.xz
#         tar -xf $tempdir/$tarname.tar.xz -C $tempdir
#         sudo cp $tempdir/$tarname/bin/node /usr/local/bin/node
#         sudo cp $tempdir/$tarname/bin/npm /usr/local/bin/npm
#         rm $tempdir/$tarname.tar.xz
#         rm $tempdir/$tarname -r
#     fi
# }

configure_git_gpg() {
    ! command_exists git && return
    [ ! -f ~/.gitconfig ] && return
    [ -n "$(git config --global user.signingkey)" ] && return

    if confirm_action "要配置 git 使用 gpg 签名吗？" "N"; then
        if [ "$(uname)" = "Darwin" ]; then
            if ! command_exists 7z; then
                brew install p7zip
            fi
        else
            if ! command_exists 7za; then
                sudo apt install p7zip-full -y
                alias 7z=7za
            fi
        fi
        read_password
        cp $scriptdir/files/git.key.zip $tempdir/git.key.zip
        7z x -p$password $tempdir/git.key.zip -o$tempdir > /dev/null 2>&1
        rm $tempdir/git.key.zip
        if [ ! -s $tempdir/git.key ]; then
            echo "Wrong password!"
            return
        fi
        gpg --import $tempdir/git.key
        rm $tempdir/git.key
        git config --global user.signingkey 93686B78EE43A65A\!
        git config --global commit.gpgSign true
    fi
}

# ============================================================

configure_swap() {
    # Input the swap size
    read -p "Swap size (MB): " swap_size
    # Create a virtual memory file
    sudo dd if=/dev/zero of=/mnt/swap bs=1M count=$swap_size
    sudo chmod 0600 /mnt/swap
    sudo mkswap /mnt/swap
    sudo swapon /mnt/swap
    # Write auto mount parameters
    if ! grep -q swap /etc/fstab; then
        echo "/mnt/swap swap swap defaults 0 0" | sudo tee -a /etc/fstab >/dev/null
    fi
    # Set virtual memory usage
    if ! grep -q swappiness /etc/sysctl.conf; then
        echo "vm.swappiness = 10" | sudo tee -a /etc/sysctl.conf >/dev/null
    else
        # sed -i 's/vm.swappiness = 0/vm.swappiness = 10/' /etc/sysctl.conf
        sudo sed -i 's/^vm.swappiness.*/vm.swappiness = 10/' /etc/sysctl.conf
    fi
    # Make the configuration take effect
    sudo sysctl -p
}

# ============================================================

if [ $# -ne 0 ]; then
    for func in $@; do
        declare -F configure_$func >/dev/null || continue
        echo "Configuring $func..."
        eval "configure_$func"
    done
    return
fi

configure_tuna
configure_upgrade
configure_install
configure_nano
configure_vim
configure_zsh
configure_zsh_prefix
configure_tmux
# configure_nodejs
configure_docker
configure_fail2ban
configure_iptables
configure_ufw
# configure_hostname
configure_timedate
configure_bootinfo
configure_oomkiller
# configure_swap
configure_node_exporter
configure_nginx_log
