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

dmidecode -t1|grep Manufacturer|grep -q -i dell
if [[ $? -eq 0 ]];then
    STORCLI='/opt/MegaRAID/perccli/perccli64'
else
    STORCLI='/opt/MegaRAID/storcli/storcli64'
fi

# delete old raid
old_raid_num=`$STORCLI /c0/vall show | grep RAID | wc -l `

if [[ $old_raid_num -le 1 ]]; then
   echo
else
   disk_raid_num=`echo ${old_raid_num}-1 | bc `
   $STORCLI /c0/v1-${disk_raid_num} delete force
   [[ $? -ne 0 ]] && echo "delete old raid failed " && echo "Delete Old Raid Failed" > /tmp/error_log && exit 1
fi

sleep 10s

HAVE_FOUND_ARR=()
slot_array=()
disk_array=()
used_disk=0
ALL_DISK_SIZE_ARR=(`$STORCLI /call/eall/sall show all | grep -i "Raw Size" | awk '{print $4}'`)

check_disk(){
disk_num=`$STORCLI /call/eall/sall show all | grep -i "Raw Size"|wc -l`
disk_uniq_size=`$STORCLI /call/eall/sall show all | grep -i "Raw Size"|awk '{print $4}'|sort -u|wc -l`
firmwa=`$STORCLI /call/eall/sall show all J|grep '"State"'|grep -v Onln|grep -v UGood|wc -l`
if [[ `expr ${disk_num} % 2` -ne 0 ]] || [[ $(echo "$disk_uniq_size > 2"|bc) -eq 1 ]] || [[ $firmwa -ne 0 ]];then
	echo "Exit Code: 018"
	echo "Please Check Disks Number OR States" > /tmp/error_log
fi
}

CALL_get_magic_numbers(){
  magic_num_arr=(`$STORCLI /call/eall/sall show all | grep -i "Raw 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'
	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
}

scan_disk_slot(){
    #find data disk enc num and slot num -> HAVE_FOUND_ARR[$m]
    m=0
    size=0
    slot=0
    for i in `/opt/MegaRAID/MegaCli/MegaCli64 -pdlist -aall|grep -i 'raw size'|awk '{print $3}'`
    do
         disk_array[$size]=$i
         size=`expr $size + 1`
    done
    for i in $($STORCLI /call/eall/sall show J|grep 'EID:Slt'|awk -F'"' '{print $4}')
    do
         slot_array[$slot]=$i
         slot=`expr $slot + 1`
    done
    for i in $(seq -f %g 0 `expr ${#slot_array[*]} - 1`)
    do

        if [ ${disk_array[$i]} = $DATA_MAGIC_NUM ];then
            HAVE_FOUND_ARR[$m]=${slot_array[$i]}
            m=`expr $m + 1`
        fi
    done

}

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

other_args=''
if [[ $raid = 'r10' ]];then
    other_args='pdperarray=2'
elif [[ $raid = 'r50' ]];then
    other_args="pdperarray=$(($do_raid_disk_num/2))"
fi

for i in $(seq -f %g 1 $raid_num)
do
    span=${HAVE_FOUND_ARR[$used_disk]}
    for n in $(seq -f %g 1 `expr $do_raid_disk_num - 1`)
    do
        used_disk=$((used_disk+1))
        slot=`echo ${HAVE_FOUND_ARR[$used_disk]}|cut -d':' -f2`
        span="$span,$slot"
    done
    used_disk=$((used_disk+1))
    $STORCLI /c0 add vd $raid drives=${span} ra $wpolicy strip=256 $other_args
    if [ $? = 0 ];then
        echo "Exit Code: 000 create ${span}"
    else
        echo "Do $raid Failed With ${span}" > /tmp/error_log
        echo "Exit Code: 012"
        exit 1
    fi
done

}

#############################start#############################################
if [ $# = 0 ] || [ $1 = "-h" ];then
    echo "Usage : ./$0 -c \"raid option\" -c \"raid option\" ..."
    echo "-c, --command  Execute argument as command"
    echo "multiple commands may be executed from the command line by passing multiple -c args"
    echo "      "
    echo "exp:do 3 sets raid10 with 4 disks"
    echo "    ./$0 -c \"4 r10 3\""
    echo "    do 3 sets raid10 with 4 disks and 1 sets raid1 with 2 disks"
    echo "    ./$0 -c \"4 r10 3\" -c \"2 r1 1\""
    echo "   "
    echo "Note:raid50 required write policy(WT or WB)"
    echo "exp:do 1 sets raid50 with 10 disks and 1 sets raid1 with 2 disks"
    echo "    ./$0 -c \"10 r50 1 WB\" -c \"2 r1 1\""
elif [ $1 != "-c" ] || [ `expr $# % 2` != 0 ];then
        echo "$0 invalid option -- $1"
        echo "Try  $0 --h' for more information."
fi
for i in `seq 1 2 $#`
do
    eval n=\$$i
    if [ $n != "-c" ];then
        eval echo "$0 invalid option -- \$$i"
        echo "Try  $0 --h' for more information."
        exit 1
    fi
done
check_disk
CALL_get_magic_numbers
sed -i "/UCLOUD_SYS_DISK_SIZE/d" /ucloud/exports.ini
echo "UCLOUD_SYS_DISK_SIZE=$SYS_MAGIC_NUM" >> /ucloud/exports.ini
scan_disk_slot

for i in `seq 2 2 $#`
do
    eval n=\$$i
    arg=`echo $n|awk '{print NF}'`
    do_raid_disk_num=`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_num"|bc`
    if [ $arg != 4 ] || [ $wp != 1 ];then
        echo "Exit Code: 001"
        echo "Need 4 Args, $arg Given" > /tmp/error_log
        exit 1
    fi
    if [ $(echo "$data_dis_num > $re_data_dis_num"|bc) -eq 1 ];then
        echo "Need Data Disks:$data_dis_num > Real Data Disks:$re_data_dis_num" > /tmp/error_log
        echo "Exit Code: 003"
        exit 1
    fi
    if [[ $raids = r1 || $raids = r10 || $raids = r50 ]];then
        if [ `expr $do_raid_disk_num % 2` != 0 ];then
            echo "Do Raid $raids Disk Numbers is $do_raid_disk_num, Wrong" > /tmp/error_log
            echo "Exit Code: 002"
            exit 1
        fi
    fi
    if [[ $raids = r10 || $raids = r50 ]];then
        if [[ $(echo "`expr $do_raid_disk_num / 2` > 1"|bc) != 1 ]];then
            echo "Do Raid $raids Disk Numbers is $do_raid_disk_num, Wrong" > /tmp/error_log
            echo "Exit Code: 007"
            exit 1
        fi
    fi
    if [[ $raids = r5 ]];then
        if [[ $(echo "$do_raid_disk_num > 2"|bc) != 1 ]];then
            echo "Do Raid $raids Disk Numbers is $do_raid_disk_num, Wrong" > /tmp/error_log
            echo "Exit Code: 007"
            exit 1
        fi
    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
