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

s=0
SLOT=`ssacli ctrl all show status | awk '/Slot/{print $6}'`
ALL_DISK_SIZE_ARR=(`ssacli ctrl slot=$SLOT pd all show status|grep physicaldrive|awk '{print $7}'`)


CALL_delete_old_raid(){
  ###### delete raid
  raid_nums=`ssacli  ctrl slot=$SLOT ld all show  | grep logicaldrive  | wc -l`
  for (( i=2; i<=$raid_nums; i++));do
      echo y | ssacli  ctrl slot=$SLOT ld $i delete
      [[ $? -ne 0 ]] && echo "delete raid failed" && echo "Delete Old Raid Failed" > /tmp/error_log && exit 1
  done
}

CALL_get_magic_numbers(){
  magic_num_arr=(`ssacli ctrl slot=$SLOT pd all show status|grep physicaldrive|awk '{print $7}'|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
}

CALL_collect_slot() {
    local j=0
    for i in `ssacli ctrl slot=$SLOT pd all show status|grep physicaldrive|awk '{print $2}'`
    do
            SLOT_ARR[$j]=$i
            j=`expr $j + 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 $3}'` -eq `expr $NEW_INDEX + 1` ]
                    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 `ssacli ctrl slot=$SLOT pd all show status|grep physicaldrive|awk '{print $7}'`
    do
            if [ $i = $MAGIC ]
            then
                    CALL_save_slot_number $j
            fi
            j=`expr $j + 1`
    done
}

do_raid() {
  do_raid_disk_num=$1
  raid=${2##*r}
  raid_num=$3
  wpolicy=$4

    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
        else
            eval span="$span,\$span$n"
        fi
        s=`expr $s + 1`
        done
        if [[ $raid = "10" ]];then
            raid=1+0
        fi
        if [[ $raid = "50" ]];then
            local args="numberparitygroups=2 size=max parityinitializationmethod=rapid"
        else
            local args=""
        fi
        ssacli ctrl slot=$SLOT create type=ld drives=${span}  raid=$raid $args forced
        if [ $? = 0 ];then
            echo "Exit Code: 000 create r${raid} (${span})"
        else
            echo "Do $raid Failed With (${span})" > /tmp/error_log
            echo "Exit Code: 111 create raid r${raid} failed"
            exit 1
        fi
    done
}

do_cache() {
  old_ld_arr=$1
  new_ld_arr=`ssacli ctrl slot=$SLOT ld all show|grep -i logicaldrive|awk '{print $2}'`
  for i in ${new_ld_arr[@]};do
      if [[ "${old_ld_arr[@]}" =~ $i ]];then
          continue
      else
          arrayid=$(ssacli ctrl slot=$SLOT ld all show|grep -E -i "array [A-Z]|logicaldrive"|grep -B1 "logicaldrive 2"|head -n1|awk '{print $NF}')
          ssacli ctrl slot=$SLOT array $arrayid modify ssdsmartpath=disable
          ssacli ctrl slot=$SLOT logicaldrive $i modify caching=enable
      if [[ $? -ne 0 ]];then
          echo "ARRAY $arrayid WritePolicy Setting Failed."
          echo "[ERROR] WritePolicy Setting Failed."
          exit 1
      fi
    fi
  done
}

################################################################################

CALL_delete_old_raid

CALL_collect_slot

# scan data 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
CALL_get_magic_raid_disk_slot_number $DATA_MAGIC_NUM


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 [ $arg != 4 ];then
        echo "Need 4 Args, $arg Given or WB/WT Not Given" > /tmp/error_log
        echo "Exit Code: 001"
        exit 1
    elif [ $(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 ];then
        if [ `expr $do_raid_disk_nums % 2` != 0 ];then
            echo "Do Raid Level $raids Disk Numbers is $do_raid_disk_num, Wrong" > /tmp/error_log
            echo "Exit Code: 002 Disks nums not available"
            exit 1
        fi
    elif [ $raids = r0 ];then
        echo
    elif [ $raids = r10 ];then
        if [ `expr $do_raid_disk_nums % 2` != 0 ] || [ $(echo "`expr $do_raid_disk_nums / 2` > 1"|bc) != 1 ];then
            echo "Do Raid Level $raids Disk Numbers is $do_raid_disk_num, Wrong" > /tmp/error_log
            echo "Exit Code: 007"
            exit 1
        fi
    elif [ $raids = r50 ];then
        if [ `expr $do_raid_disk_nums % 2` != 0 ] || [ $(echo "`expr $do_raid_disk_nums / 2` > 2"|bc) != 1 ];then
            echo "Do Raid Level $raids Disk Numbers is $do_raid_disk_num, Wrong" > /tmp/error_log
            echo "Exit Code: 008"
            exit 1
        fi
    elif [[ $raids = r5 ]];then
        if [[ $do_raid_disk_nums -lt 3 ]];then
            echo "Do Raid Level $raids Disk Numbers is $do_raid_disk_num, Wrong" > /tmp/error_log
            echo "Exit Code: 009"
            exit 1
        fi
    else
        echo "Unknow Raid Level $raids" > /tmp/error_log
        echo "Exit Code: 017 Not available raid level"
        exit 1
    fi
done

for i in `seq 2 2 $#`
do
    echo "============="
    eval n=\$$i
    arg=`echo $n|awk '{print NF}'`
    one_raid_disk_nums=`echo $n|awk '{print $1}'`
    raid_type=`echo $n|awk '{print $2}'`
    raid_num=`echo $n|awk '{print $3}'`
    wpolicy=`echo $n|awk '{print $4}'`
    old_ld_arr=`ssacli ctrl slot=$SLOT ld all show|grep -i logicaldrive|awk '{print $2}'`
#   echo $one_raid_disk_nums $raid_type $raid_num
    do_raid $one_raid_disk_nums $raid_type $raid_num $wpolicy

#   sleep 120s make sure raid exist
    ManufactureType=$(cat /tmp/os_init/cmdb.info|egrep ^ManufactureType|awk -F ":" '{print $2}')
    if [[ $ManufactureType =~ 'ProLiant DL380 Gen9' && $raid_type = 'r50' ]];then
        sleep 1500
    else
        sleep 120
    fi

#   effect LD caching
    if [[ $? -eq 0 ]] && [[ $wpolicy = WB ]];then
        do_cache $old_ld_arr
    fi
done
