#!/usr/bin/env bash

set -u

SERVICE_NAME="L1_proxy"
LOG_DIR="/home/log/L1_proxy"
CHECK_DATE="$(date +%F)"
JOURNAL_LINES=10000
RUN_LOG_LINES=20000
ALARM_LOG_LINES=20000
GREP_COLOR_OPTION="--color=always"
HIGHLIGHT_PATTERN="restart|panic|error|fail|failed|invalid|critical"

RUN_LOG="${LOG_DIR}/run.log"
ALARM_LOG="${LOG_DIR}/alarm.log"

print_section() {
    printf '\n===== %s =====\n' "$1"
}

print_missing() {
    printf '[skip] file is missing or unreadable: %s\n' "$1"
}

highlight_stream() {
    local extra_pattern="${1:-}"
    local pattern="$HIGHLIGHT_PATTERN"

    if [[ -n "$extra_pattern" ]]; then
        pattern="${pattern}|${extra_pattern}"
    fi

    grep $GREP_COLOR_OPTION -iE "${pattern}|$" || true
}

grep_one() {
    local pattern="$1"
    local file="$2"

    if [[ ! -r "$file" ]]; then
        print_missing "$file"
        return 0
    fi

    grep $GREP_COLOR_OPTION -F -- "$pattern" "$file" || true
}

grep_many() {
    local pattern="$1"
    shift
    local file
    local readable_files=()

    for file in "$@"; do
        [[ -r "$file" ]] && readable_files+=("$file")
    done

    if ((${#readable_files[@]} == 0)); then
        printf '[skip] no readable files matched the requested path\n'
        return 0
    fi

    grep $GREP_COLOR_OPTION -F -- "$pattern" "${readable_files[@]}" || true
}

filter_error_file() {
    local file="$1"

    if [[ ! -r "$file" ]]; then
        print_missing "$file"
        return 0
    fi

    grep -v "handshake error" "$file" \
        | grep -v runner \
        | grep -v promtail \
        | grep -vi yunxiao \
        | grep -v "reading preface from client" \
	| grep -v keepalive \
        | grep -iE "error|fail|failed|invalid|critical|panic" \
        | highlight_stream
}

filter_run_errors() {
    if [[ ! -r "$RUN_LOG" ]]; then
        print_missing "$RUN_LOG"
        return 0
    fi

    tail -n "$RUN_LOG_LINES" "$RUN_LOG" \
        | grep -iE "error|failed|invalid" \
        | grep -v handshake \
        | grep -v response \
        | grep -vi yunxiao \
        | grep -v "Permission Denied" \
        | grep -v "invalid character" \
        | grep -v "context deadline exceeded" \
        | grep -v 1006 \
	| grep -v trace \
	| grep -v keepalive \
	| grep -v "ConnFailedReason:" \
	| grep -v "err:tlv_client_respcode:9" \
	| grep -v "err:tlv_client_respcode:10" \
	| grep -v "err:tlv_client_respcode:11" \
        | highlight_stream
}

filter_alarm_errors() {
    if [[ ! -r "$ALARM_LOG" ]]; then
        print_missing "$ALARM_LOG"
        return 0
    fi

    tail -n "$ALARM_LOG_LINES" "$ALARM_LOG" \
        | grep -F -- "$CHECK_DATE" \
        | grep -v DeleteConn \
        | grep -v black_token \
        | grep -vi yunxiao \
        | grep -v "invalid character" \
        | grep -v "context deadline exceeded" \
        | grep -v 1006 \
        | grep -v "Permission Denied" \
        | highlight_stream "$CHECK_DATE"
}

run_journal_panic() {
    if ! command -v journalctl >/dev/null 2>&1; then
        printf '[skip] journalctl is not installed\n'
        return 0
    fi

    journalctl --no-pager -n "$JOURNAL_LINES" \
        | grep $GREP_COLOR_OPTION -F -- "panic" || true
}

run_journal_errors() {
    if ! command -v journalctl >/dev/null 2>&1; then
        printf '[skip] journalctl is not installed\n'
        return 0
    fi

    journalctl --no-pager -n "$JOURNAL_LINES" \
        | grep -iE "error|failed|invalid" \
        | grep -v promtail \
        | grep -v handshake \
        | grep -vi yunxiao \
	| grep -v "http: TLS handshake" \
        | highlight_stream
}

print_section "run.log: restart"
grep_one "restart" "$RUN_LOG"

shopt -s nullglob
MESSAGE_FILES=(/var/log/messages*)
shopt -u nullglob

print_section "messages*: panic"
grep_many "panic" "${MESSAGE_FILES[@]}"

print_section "syslog: panic"
grep_one "panic" /var/log/syslog

print_section "syslog.1: panic"
grep_one "panic" /var/log/syslog.1

print_section "messages*: filtered errors"
for file in "${MESSAGE_FILES[@]}"; do
    filter_error_file "$file"
done
if ((${#MESSAGE_FILES[@]} == 0)); then
    printf '[skip] no /var/log/messages* files found\n'
fi

print_section "syslog: filtered errors"
filter_error_file /var/log/syslog

print_section "syslog.1: filtered errors"
filter_error_file /var/log/syslog.1

print_section "journal: panic"
run_journal_panic

print_section "journal: filtered errors"
run_journal_errors

print_section "systemctl status: ${SERVICE_NAME}"
if command -v systemctl >/dev/null 2>&1; then
    systemctl status "$SERVICE_NAME" --no-pager --full 2>&1 | highlight_stream
else
    printf '[skip] systemctl is not installed\n'
fi

print_section "run.log: recent errors"
filter_run_errors

print_section "alarm.log: ${CHECK_DATE}"
filter_alarm_errors
