#!/bin/bash

# Just in case PATH is not set.
PATH=$PATH:/bin:/usr/bin:/usr/local/bin

info() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') [INFO] $*"
}

warn() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') [WARN] $*"
}

error() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') [ERRO] $*"
}

# must have curl installed
if ! which curl >/dev/null; then
    error "请先安装 curl"
    exit 1
fi

ask_cred() {
    # already set username and password in environment variables, skip
    if [[ -n "$BUPT_USERNAME" && -n "$BUPT_PASSWORD" ]]; then
        return
    fi

    # try to read saved username and password from file
    if [[ -f $HOME/.bupt-net-login ]]; then
        source $HOME/.bupt-net-login
    fi

    # if still not set, ask user to input
    if [[ -z "$BUPT_USERNAME" || -z "$BUPT_PASSWORD" ]]; then
        warn "你没有设置 BUPT_USERNAME 和 BUPT_PASSWORD 环境变量（例如 \"BUPT_USERNAME=2019000000 BUPT_PASSWORD=123456 $0\"），也没有保存密码。"
        echo "请手动输入学号和网关密码，你的信息将用于网关认证。"
        read -p '你的学号 Username: ' BUPT_USERNAME
        read -s -p '网关密码 Password: ' BUPT_PASSWORD
        echo

        read -p "是否保存用户名密码以方便手动登录（自动登录不需要）？注意，你的凭据将被明文存储。(y/n) " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            echo "BUPT_USERNAME='$BUPT_USERNAME'" >$HOME/.bupt-net-login
            echo "BUPT_PASSWORD='$BUPT_PASSWORD'" >>$HOME/.bupt-net-login
            chmod 600 $HOME/.bupt-net-login
            info "已保存你的凭据至 $HOME/.bupt-net-login ，如果你想删除凭据，请直接删除该文件。"
        fi
    fi
}

# Installation

if [[ "$1" == "install" ]]; then
    if ! cat "$0" 2>/dev/null | head -n1 | grep -q '#!/bin/bash'; then
        error "请从本地运行 bupt-net-login "
        exit 1
    fi

    if [[ -z $PREFIX ]]; then
        PREFIX=/usr/local/bin
    fi

    cron="0-59/5 * * * *"
    # Use user-specified cron, if possible.
    if [[ "$2" != "" ]]; then
        cron="$2"
    fi

    echo "你将要安装 bupt-net-login , 安装脚本将会做以下这些事："
    if [[ "$0" != "$PREFIX/bupt-net-login" ]]; then
        echo "  - 安装 $0 至 $PREFIX/bupt-net-login 。如果你希望更改目标位置, 请设置 PREFIX 环境变量。"
    fi
    if crontab -l | grep -q "/bupt-net-login"; then
        echo "  - 移除先前安装的 bupt-net-login cron job 。其他 cron job 不受影响。"
    fi
    echo "  - 安装 cron job ($cron) 至当前用户 $USER 。如果你需要自定义 cron , 添加命令行参数即可, 例如 $0 install \"$cron\"。"

    read -p "是否继续? (y/n) " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo "你选择了取消安装"
        exit 1
    fi

    mkdir -p "$PREFIX"
    if [[ "$0" != "$PREFIX/bupt-net-login" ]] && ! install "$0" "$PREFIX/bupt-net-login"; then
        error "安装失败"
        if [[ $EUID -ne 0 && $PREFIX == "/usr/local/bin" ]]; then
            echo "默认安装位置 /usr/local/bin 需要 root 权限, 你需要以 root 权限运行 (sudo)。"
            echo "如果你不想用 root 账户，请设置 PREFIX 环境变量以改变安装位置。"
        fi
        exit 1
    fi

    ask_cred

    cronfull="$cron BUPT_USERNAME='$BUPT_USERNAME' BUPT_PASSWORD='$BUPT_PASSWORD' $PREFIX/bupt-net-login >>/tmp/bupt-net-login.log 2>&1"

    if ! crontab -l 2>/dev/null | sed -e "\_/bupt-net-login_d" | echo -e "$(cat -)\n$cronfull\n" | crontab -; then
        error "安装失败"
        exit 1
    fi

    info "安装成功"
    exit 0
fi

if [[ -z "$REDIRECTION_TEST_URL" ]]; then
    REDIRECTION_TEST_URL="http://captive.apple.com/"
fi

debug_args=""
if [[ -n "$DEBUG" ]]; then
    debug_args+="-v"
fi

cookie_file=$(mktemp)

cleanup() {
    rm -f "$cookie_file"
}

trap cleanup EXIT

login() {
    redirected_auth_url=$1
    if [[ -z "$redirected_auth_url" ]]; then
        error "未指定认证地址"
        return 1
    fi

    info "准备使用账号 $BUPT_USERNAME 进行认证, 认证地址 $redirected_auth_url"

    info "获取 cookie ..."
    if ! curl $debug_args \
        -s -c "$cookie_file" \
        "$redirected_auth_url" >/dev/null; then
        error "获取 cookie 失败"
        return 1
    fi

    info "正在认证..."
    if ! curl $debug_args \
        -s -b "$cookie_file" \
        -X POST \
        --data-urlencode "user=$BUPT_USERNAME" \
        --data-urlencode "pass=$BUPT_PASSWORD" \
        "${redirected_auth_url/index/login}" >/dev/null; then
        error "发送登录请求失败, 请检查网络连接"
        return 1
    fi

    test_login
}

test_login() {
    curl $debug_args -4s "${REDIRECTION_TEST_URL}" | grep -q "Success"
}

check_response() {
    redirect_resp=$1
    if [[ $redirect_resp == *Success* ]]; then
        info "您已经登录, 无需进一步操作"
        exit 0
    elif [[ $redirect_resp == *10.3.8* ]]; then
        info "您未登录, 准备认证..."
        ask_cred
        if login "$redirect_resp"; then
            info "账号 $BUPT_USERNAME 认证成功"
            exit 0
        else
            error "账号 $BUPT_USERNAME 认证失败"
            exit 1
        fi
    elif [[ $redirect_resp == *http-equiv* ]]; then # 无线网，多一次跳转
        redirect_resp=$(echo "$redirect_resp " | grep -o "url=.*'")
        redirect_resp=${redirect_resp/url=/}
        redirect_resp=${redirect_resp/\'/}
        REDIRECTION_TEST_URL="${redirect_resp}"
        main
    else
        error "收到来自 $REDIRECTION_TEST_URL 的未知响应: \"$redirect_resp\" 本次认证失败, 以下为 debug 信息"
        curl -4vsS "${REDIRECTION_TEST_URL}"
        exit 1
    fi
}

main() {
    redirect_resp="$(curl $debug_args -4sS -w '%{redirect_url}' "${REDIRECTION_TEST_URL}")"
    check_response "$redirect_resp"
}

main
