#!/bin/bash
# set -x

function error_quit() {
    echo "$1" > /dev/null 2>&1
    exit 1
}

# detect vm
function detect_vm() {
    `cat /proc/cpuinfo | grep 'flags' | grep -q 'hypervisor'`
    if [ $? -eq 0 ]; then
        error_quit "Not Support VM"
    fi
}

function check_cmd_exist() {
    local cmd=$1
    type $cmd > /dev/null 2>&1 || {
        echo >&2 "require command [$cmd] but it's not installed. Aborting."
        exit 1
    }
}

function collect_shannon_info() {
    detect_vm

    check_if_shannon_ssd=`ls /dev/df[a-z] > /dev/null 2>&1`
    if [ $? -eq 0 ]; then
        shannon_ssd_collect $@
    else
        error_quit "No Shannon SSD here"
    fi
}

CMD_PERL="/usr/bin/perl"
CMD_SHANNON="/root/shannon-status"

function join_string() {
    local arr=("${!2}")
    local result=$(printf "$1%s" "${arr[@]}")
    result=${result:1}
    echo -n $result
}

function get_value() {
    local ori_str="$1"
    local trim_cmd="awk"
    if [ $# -gt 1 ] && [ "$2" != " " ]; then
        trim_cmd="$trim_cmd -F$2"
    fi

    local result=$($trim_cmd '{
        gsub(/^[ \t]+/, "", $2);
        gsub(/[ \t]+$/, "", $2);
        print $2}' <<< "$ori_str")
    echo -n $result
}

function shannon_ssd_status() {
    local flag=$1
    local shannons=$(get_shannons)
    local status=()
    local PCIE="Shannon"
    local i=0

    for shannon in ${shannons[@]}; do
        local shannon_info=$(shannon_monitor_items $shannon)
        local shannonstatus
        case "$flag" in
            access_mode)
                shannonstatus=$(grep "Access Mode" <<< "$shannon_info" | awk -F"[:, ]" '{print $NF}')
                if [ "$shannonstatus" == "readwrite" ];then
                    value=0
                else
                    value=1
                fi
                tag_value='"pcie_type='$PCIE',shannon_device=/dev/'$shannon',access_mode='$shannonstatus'"'
                ;;
            ctrl_temp)
                shannonstatus=$(get_value "$(grep "Controller Temperature" <<< "$shannon_info")" ":" )
                value=$shannonstatus
                tag_value='"pcie_type='$PCIE',shannon_device=/dev/'$shannon'"'
                ;;
            flash_temp)
                shannonstatus=$(get_value "$(grep "Flash Temperature" <<< "$shannon_info")" ":")
                value=$shannonstatus
                tag_value='"pcie_type='$PCIE',shannon_device=/dev/'$shannon'"'
                ;;
            life_left)
                shannonstatus=$(get_value "$(grep "Estimated Life Left" <<< "$shannon_info")" ":")
                value=$shannonstatus
                tag_value='"pcie_type='$PCIE',shannon_device=/dev/'$shannon'"'
                ;;
            crc_err)
                shannonstatus=$(get_value "$(grep "SEU CRC Error" <<< "$shannon_info")" ":")
                value=$shannonstatus
                tag_value='"pcie_type='$PCIE',shannon_device=/dev/'$shannon'"'
                ;;
            ecc_err)
                shannonstatus=$(get_value "$(grep "SEU ECC Error" <<< "$shannon_info")" ":")
                value=$shannonstatus
                tag_value='"pcie_type='$PCIE',shannon_device=/dev/'$shannon'"'
                ;;
            *)
                exit 1
                ;;
            esac
        if [ -z "$shannonstatus" ]; then
            continue
        fi
        status[i]='{"value": '$value', "tags": '$tag_value'}'
        ((i++))
    done

    local laststatus=$(join_string "," status[@])
    echo -n "[$laststatus]"
}

function shannon_monitor_items() {
    local disk=$1
    local access_mode
    local temperature_int
    local temperature_flash
    local estimated_life_left
    local seu_crc_error
    local seu_ecc_error

    access_mode=`cat /sys/block/$disk/shannon/access_mode`
    temperature_int=`cat /sys/block/$disk/shannon/temperature_int`
    temperature_flash=`cat /sys/block/$disk/shannon/temperature_flash`
    estimated_life_left=`cat /sys/block/$disk/shannon/estimated_life_left`
    seu_crc_error=`cat /sys/block/$disk/shannon/seu_crc_error`
    seu_ecc_error=`cat /sys/block/$disk/shannon/seu_ecc_error`

    echo -e "Access Mode: $access_mode\nController Temperature: $temperature_int\nFlash Temperature: $temperature_flash\nEstimated Life Left: $estimated_life_left\nSEU CRC Error: $seu_crc_error\nSEU ECC Error: $seu_ecc_error"
}

function get_shannons() {
    local result=$(ls /dev/df[a-z] | awk -F"/" '{print $NF}')
    echo -n $result
}

function shannon_ssd_collect() {
    check_cmd_exist $CMD_PERL

    while getopts m: o; do
        case "$o" in
            m)
                local opt=$OPTARG
                shannon_ssd_status $opt
                ;;
            *)
                exit 1
                ;;
            esac
        done
}

collect_shannon_info $@
