#!/bin/bash
PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' 

s=0

CALL_get_dev_id(){
    ARCCONF=`which arcconf`
    if [ -z $ARCCONF ];then
        return 1
    else
        DEV_ID=`$ARCCONF list|grep -i 'Controller [0-9]'|awk -F ':' '{print $1}'|awk '{print $2}'`
        ALL_DISK_SIZE_ARR=(`$ARCCONF getconfig $DEV_ID pd|grep "Total Size"|awk '{print $4}'`)
    fi
}

CALL_delete_old_raid(){
    raid_nums=`$ARCCONF getconfig $DEV_ID LD|grep "Logical Device number"|awk '{print $4}'`
    for i in $raid_nums;do
        if [ $i -ne 0 ];then
            $ARCCONF delete $DEV_ID logicaldrive $i noprompt 2>/dev/null >&2
            [[ $? -ne 0 ]] && echo "delete raid failed" && exit 1
        fi
    done

}

CALL_collect_slot_number() {
    local j=0
    for i in `$ARCCONF getconfig $DEV_ID PD|grep "Reported Channel,Device(T:L)"|awk -F ": " '{print $2}'|awk -F "(" '{print $1}'`
    do
            SLOT_ARR[$j]=$i
            j=`expr $j + 1`
    done
    #echo ${SLOT_ARR[*]}
    #echo -e "\n"
}

CALL_get_magic_numbers(){
    magic_num_arr=(`$ARCCONF getconfig $DEV_ID pd|grep "Total Size"|awk '{print $4}'|sort -u`)
    newlen=${#magic_num_arr[@]}
    if [[ $newlen -lt 1 ]] || [[ $newlen -gt 2 ]]; then
        return 1
    elif [[ $newlen -eq 1 ]]; then
        SYS_MAGIC_NUM=${magic_num_arr[0]}
        DATA_MAGIC_NUM='NoDataDiskFound'
        sed -i "/UCLOUD_SYS_DISK_SIZE/d" /ucloud/exports.ini
        echo "UCLOUD_SYS_DISK_SIZE=$MAGIC_NUM_1" >> /ucloud/exports.ini
    elif [[ $newlen -eq 2  ]]; then
        MAGIC_NUM_1=${magic_num_arr[0]}
        MAGIC_NUM_2=${magic_num_arr[1]}
        NUM_1_COUNT=0
        NUM_2_COUNT=0
        for i in ${ALL_DISK_SIZE_ARR[@]}; do
            if [[ $i = $MAGIC_NUM_1 ]];then
                NUM_1_COUNT=`expr $NUM_1_COUNT + 1`
            else
                NUM_2_COUNT=`expr $NUM_2_COUNT + 1`
            fi
        done
        if [[ $NUM_1_COUNT -le $NUM_2_COUNT ]];then
            SYS_MAGIC_NUM=$MAGIC_NUM_1
            DATA_MAGIC_NUM=$MAGIC_NUM_2
        else
            SYS_MAGIC_NUM=$MAGIC_NUM_2
            DATA_MAGIC_NUM=$MAGIC_NUM_1
    fi
  fi
}

CALL_get_all_slot_number() {
        m=0
        for k in `$ARCCONF getconfig $DEV_ID PD|grep "Reported Location"|awk -F ':' '{print $2}'|awk '{print $2 $4}'|awk -F '(' '{print $1}'`
        do
                SLOT_ARR[$m]=$k
                m=`expr $m + 1`
        done
}

CALL_save_slot_number() {
        local NEW_INDEX=$1
        local ARR_SIZE=${#HAVE_FOUND_ARR[@]}

        local i=0
    if [ $ARR_SIZE -eq 0 ]
    then
            DEV_INDEX=$NEW_INDEX
            HAVE_FOUND_ARR[$ARR_SIZE]=${SLOT_ARR[$NEW_INDEX]}
    else
            while [ $i -lt $ARR_SIZE ]
            do
                    if [ `echo ${HAVE_FOUND_ARR[$i]}|awk -F ',' '{print $2}'` -eq $NEW_INDEX ]
                    then
                            return 0
                    fi
                    i=`expr $i + 1`
            done
            HAVE_FOUND_ARR[$ARR_SIZE]=${SLOT_ARR[$NEW_INDEX]}
    fi
}

CALL_get_magic_raid_disk_slot_number() {
    local MAGIC=$1
    local j=0
    for i in `$ARCCONF getconfig $DEV_ID PD|grep "Total Size"|awk '{print $4}'`
    do
            if [ $i = $MAGIC ]
            then
                    CALL_save_slot_number $j
            fi
            j=`expr $j + 1`
    done
}

create_unit() {
    local policy=$1
    local rtype=$2
    local disks=`echo $3|sed 's/,/ /g'`
        $ARCCONF create $DEV_ID logicaldrive Wcache $policy method quick MAX $rtype $disks noprompt 2>/dev/null >&2
    if [[ $? -eq 0 ]];then
        return 0
    fi
    local ld=$($ARCCONF create $DEV_ID logicaldrive method quick MAX $rtype $disks noprompt|grep LogicalDrv|awk '{print $NF}')
    if [[ $? -ne 0 ]];then
        return 1
    fi
    if [[ $policy = 'WB' ]];then
        $ARCCONF setarrayparam $DEV_ID $ld ssdiobypass disable 2>/dev/null >&2
        $ARCCONF setcache $DEV_ID logicaldrive $ld con 2>/dev/null >&2
    fi
    return 0
}

do_raid(){
do_raid_disk_num=$1
raid=$2
raid_num=$3
wpolicy=$4
allwpolicy=(WB WT)

if [[ " ${allwpolicy[@]} " =~ " $wpolicy " ]];then
        :
else
    echo "003:write policy not match"
    exit 1
fi


    raid_type=${raid##r}
    for i in $(seq -f %g 1 $raid_num)
    do
        span=${HAVE_FOUND_ARR[$s]}
        for n in $(seq -f %g 0 `expr $do_raid_disk_num - 1`)
        do
            eval span$n=${HAVE_FOUND_ARR[$s]}
            if [ $do_raid_disk_num = 1 ] || [ $n = 0 ];then
                span=$span
                if [[ $raid_type = 0 ]];then
                    raid_type=simple_volume
                fi
            else
                eval span="$span,\$span$n"
            fi
            s=`expr $s + 1`
        done
        create_unit $wpolicy $raid_type $span
        if [[ $? -eq 0 ]];then
            echo "Exit Code: 000 create $raid(${span})"
        else
            echo "Exit Code: 111 create $raid failed"
            exit 1
        fi
    done
}

#############################start#############################################
# begins here
CALL_get_dev_id
if [ $? -ne 0 ];then
        echo "CanNotFindCommand"
        exit 1
fi

CALL_delete_old_raid

CALL_collect_slot_number

# scan data disk
CALL_get_magic_numbers
CALL_get_magic_raid_disk_slot_number $DATA_MAGIC_NUM

for i in ${HAVE_FOUND_ARR[@]}
do
    $ARCCONF task start $DEV_ID device `echo $i|sed 's/,/ /g'` initialize noprompt 2>/dev/null >&2
    if [ $? -ne 0 ];then
        echo "DISK(`echo $i|sed 's/,/ /g'`) initialize failure"
    fi
done

for i in `seq 2 2 $#`
do
        eval n=\$$i
        arg=`echo $n|awk '{print NF}'`
        do_raid_disk_nums=`echo $n|awk '{print $1}'`
        raids=`echo $n|awk '{print $2}'`
        raid_nums=`echo $n|awk '{print $3}'`
        wp=`echo $n|awk '{print $4}'|grep -E "WB|WT"|wc -l`
        re_data_dis_num=${#HAVE_FOUND_ARR[*]}
        data_dis_num=`echo "$raid_nums * $do_raid_disk_nums"|bc`

                if [ $raids = r1 ];then
                    if [ $arg != 4 ];then
                        echo "Exit Code: 001 Args nums not 4"
                        exit 1
                    elif [ `expr $do_raid_disk_nums % 2` != 0 ];then
                        echo "Exit Code: 002 Disks nums not available"
                        exit 1
                    elif [ $(echo "$data_dis_num > $re_data_dis_num"|bc) -eq 1 ];then
                        echo "Exit Code: 003 Need Disks not match real Disks number"
                        exit 1
                    fi
                elif [[ $raids = r0 || $raids = r5 ]];then
                            if [ $arg != 4 ];then
                                    echo "Exit Code: 004"
                                    exit 1
                            elif [ $(echo "$data_dis_num > $re_data_dis_num"|bc) -eq 1 ];then
                                    echo "Exit Code: 005"
                                    exit 1
                            fi
                elif [ $raids = r10 ];then
                            if [ $arg != 4 ];then
                                    echo "Exit Code: 006"
                                    exit 1
                            elif [ `expr $do_raid_disk_nums % 2` != 0 ] || [ $(echo "`expr $do_raid_disk_nums / 2` > 1"|bc) != 1 ];then
                                    echo "Exit Code: 007"
                                    exit 1
                            elif [ $(echo "$data_dis_num > $re_data_dis_num"|bc) -eq 1 ];then
                                    echo "Exit Code: 008"
                                    exit 1
                            fi
                elif [ $raids = r50 ];then
                            if [ $arg != 4 ] || [ $wp != 1 ];then
                                    echo "Exit Code: 009"
                                    exit 1
                            elif [ `expr $do_raid_disk_nums % 2` != 0 ] || [ $(echo "`expr $do_raid_disk_nums / 2` > 2"|bc) != 1 ];then
                                    echo "Exit Code: 010"
                                    exit 1
                            elif [ $(echo "$data_dis_num > $re_data_dis_num"|bc) -eq 1 ];then
                                    echo "Exit Code: 011"
                                    exit 1
                            fi
                else
                    echo "Exit Code: 017 Not available raid level"
                    exit 1
                    fi
done

for i in `seq 2 2 $#`
do
    eval n=\$$i
    arg=`echo $n|awk '{print NF}'`
    do_raid_disk_nums=`echo $n|awk '{print $1}'`
    raids=`echo $n|awk '{print $2}'`
    raid_nums=`echo $n|awk '{print $3}'`
    wpolicys=`echo $n|awk '{print $4}'`
    do_raid $do_raid_disk_nums $raids $raid_nums $wpolicys
done
