#!/bin/bash

check_permission() {
  if [[ `whoami` != 'root' ]]; then
    echo "pcdn requires root privileges to install."
    echo "please run this script as root."
    exit 1
  fi 
}
check_permission

print_usage() {
echo "
Usage: sh install_p2p.sh [OPTION]   (chmod 777 install_p2p.sh)

  --platform             platform
  --version              pcnd version
"
exit 1
}

PLATFORM="PEAR_2601_X64_LINUX"
PCDN_VERSION="524"
PARAMS=$@
check_params() {
  number=0
	for arg in ${PARAMS}; do
		kv=${arg:2}
		kv=${kv//=/ }

    declare -a arr
		for k in ${kv[@]}; do 
      arr[${#arr[@]}]=${k}
    done
    
    case ${arr[0]} in
      platform)
        PLATFORM=${arr[1]}
        ;;
      version)
        PCDN_VERSION=${arr[1]}
        ;;
      *)
        print_usage
        ;;
    esac
		number=`expr ${number} + 1`
  done

  if [ ${number} -eq 0 ]; then
    print_usage
  fi
}
check_params

echo "start installing pcdn..."

install_docker() {
  version=`docker -v 2>/dev/null | awk -F ',' '{print $1}' | awk '{print $3}'`
  if [ "1${version}" != "1" ]; then
    echo "docker have already been installed, version ${version}"
    return
  fi

  # install
  sudo apt  -y remove    docker docker-engine docker.io
  sudo apt  -y install
  sudo apt  -y install   apt-transport-https
  sudo apt  -y install   ca-certificates
  sudo apt  -y install   curl
  sudo apt  -y install   software-properties-common

  curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  sudo add-apt-repository  "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs)  stable"
  sudo apt   update
  sudo apt  -y install docker-ce
  sudo docker version

  sudo groupadd docker
  sudo gpasswd -a ${USER} docker
  sudo service docker restart
  newgrp - docker
}
install_docker

# generate mount command
DATA_DISK_TYPE="xfs"
PART_SIZE=380
PART_NUMBER=5
base_mount_cmd="mount -o rw,noatime,nodiratime,lazytime"
base_remount_cmd="mount -o rw,remount,noatime,nodiratime,lazytime"
generate_mount_cmd() {
  if [[ ${DATA_DISK_TYPE} == "exfat" ]]; then
    echo "exfat..."
  elif [[ ${DATA_DISK_TYPE} == "xfs" ]]; then
    base_mount_cmd="${base_mount_cmd},noiversion,noquota"
    base_remount_cmd="${base_remount_cmd},noiversion,attr2,inode64"
  elif [[ ${DATA_DISK_TYPE} == "ext4" ]]; then
    echo "ext4..."
    base_mount_cmd="${base_mount_cmd},noiversion,noquota,nobarrier"
    base_remount_cmd="${base_remount_cmd},noiversion,noquota,nobarrier"
  else
    echo "data disk type unknown..."
  fi
}
generate_mount_cmd

#
rootdisk=""
get_root_disk() {
  rootfilesystemname=`df -hT | grep ext4 | grep -e '/$' | awk '{print $1}' | awk -F/ '{print $3}'`
  # echo "root system: " ${rootfilesystemname}
  disks=`lsblk -o NAME,TYPE | grep disk  | awk '{print $1}'`
  rootdisk=${rootfilesystemname}
  for disk in ${disks[@]}; do
    length=${#disk}
    if [[ ${rootfilesystemname:0:${length}} == ${disk} ]]; then
      rootdisk=${disk}
      # echo "get root disk: " ${rootdisk}
      break
    fi
  done
}

# parted 
declare -a dataDisks 
get_data_disks() {
  blkDisks=`lsblk  | grep disk | grep -v loop | grep T | awk '{system("echo /dev/" $1)}'`
  blkDisks=(${blkDisks})
  for part in ${blkDisks[@]}; do
    outputresult=`fdisk -l ${part} `
    if [[ -z ${outputresult} ]]; then
      echo "Disk "${part} "Read Erro, chekc file:  ${LOGDIR}/fdisk_error"
      errorresult=`fdisk -l ${part} 2>&1`
      echo ${part} ": " ${errorresult} 
      continue
    fi
    dataDisks[${#dataDisks[@]}]=${part}
  done
}
get_data_disks

declare -a AVAILABLE_PARTITIONS
DISK_NUMBER=${#dataDisks[@]}
ALLPARTSNUMBER=`expr  ${DISK_NUMBER} \* ${PART_NUMBER} `
part_all_disks() {
  echo "PART_SIZE:" ${PART_SIZE} " PART_NUMBER:" ${PART_NUMBER} " Total PARTS: "  ${ALLPARTSNUMBER}

  rootfilesystemname=`df -hT | grep ext4 | grep -e '/$' | awk '{print $1}'`

  for part in ${dataDisks[@]}; do
    echo "checking " ${part}
    length=${#part}
    if [[ ${rootfilesystemname:0:${length}} == ${part} ]]; then
      echo "skip root system " ${rootfilesystemname}
      continue
    fi

    mountpoints=` df | grep ${part} | awk '{print $6}' `
    if [[ -n ${mountpoints} ]]; then
      for mountpoint in ${mountpoints[@]}; do
        cmd="umount ${mountpoint}"
        ${cmd} 2> temp
        if [[ -n ${temp} ]]; then
          echo ${temp}  
          break
        fi
      done
    fi

    mountpoints=` df | grep ${part} | awk '{print $6}' `
    if [[ -n ${mountpoints} ]]; then
      echo ${part} "is busy, could not be umounted "
      echo "pear_part: " ${part} "is busy"  >> /root/pear/${PEAR_MACHINE_NAME}_parm.conf
      continue
    fi

    if [[ ${PART_NUMBER} == "1" ]]; then
      cmd="parted --script ${part} mklabel gpt mkpart primary 100MiB ${PART_SIZE}GiB"
    elif [[  ${PART_NUMBER} == "5"  ]]; then
      cmd="parted --script ${part} mklabel gpt \
        mkpart primary  100MiB                ${PART_SIZE}GiB  \
        mkpart primary  ${PART_SIZE}GiB        $(( PART_SIZE*2 ))GiB \
        mkpart primary  $(( PART_SIZE*2 ))GiB $(( PART_SIZE*3 ))GiB \
        mkpart primary  $(( PART_SIZE*3 ))GiB $(( PART_SIZE*4 ))GiB \
        mkpart primary  $(( PART_SIZE*4 ))GiB $(( PART_SIZE*5 ))GiB"
    elif [[  ${PART_NUMBER} == "10"  ]]; then
      cmd="parted --script ${part} mklabel gpt \
        mkpart primary  100MiB                ${PART_SIZE}GiB  \
        mkpart primary  ${PART_SIZE}GiB        $(( PART_SIZE*2 ))GiB \
        mkpart primary  $(( PART_SIZE*2 ))GiB $(( PART_SIZE*3 ))GiB \
        mkpart primary  $(( PART_SIZE*3 ))GiB $(( PART_SIZE*4 ))GiB \
        mkpart primary  $(( PART_SIZE*4 ))GiB $(( PART_SIZE*5 ))GiB\
        mkpart primary  $(( PART_SIZE*5 ))GiB $(( PART_SIZE*6 ))GiB \
        mkpart primary  $(( PART_SIZE*6 ))GiB $(( PART_SIZE*7 ))GiB \
        mkpart primary  $(( PART_SIZE*7 ))GiB $(( PART_SIZE*8 ))GiB \
        mkpart primary  $(( PART_SIZE*8 ))GiB $(( PART_SIZE*9 ))GiB \
        mkpart primary  $(( PART_SIZE*9 ))GiB $(( PART_SIZE*10 ))GiB"
    else
      echo $part
      disk_size=`lsblk ${part} -b -o SIZE  | grep -m 1  -vi SIZE`
      echo disk size is  $disk_size
      disk_size=$(( ${disk_size} / 1000 / 1000 / 1000 ))
      max_parts=$(( ${disk_size} / ${PART_SIZE}  ))
      echo $disk_size $PART_NUMBER $PART_SIZE   $max_parts
      if expr ${PART_NUMBER} > ${max_parts}; then
        echo "too many parts"
        PART_NUMBER=${max_parts}
      fi
      PART_NUMBER=${max_parts}
      echo $disk_size $PART_NUMBER  $PART_SIZE   $max_parts

      cmd="parted --script ${part} mklabel gpt "
      for k in `seq 0 $((PART_NUMBER-1))`; do
        if expr $k = 0; then
          cmd=${cmd}"mkpart primary  100MiB  ${PART_SIZE}GiB "
          continue
        fi
        cmd=${cmd}"mkpart primary  $(( PART_SIZE*k))GiB $(( PART_SIZE*(k+1) ))GiB "
      done
    fi
    # echo ${cmd}

    # for support which partition to parted 
    if [ "l${SELECT_PARTITON}" = "lTRUE" ]; then
      echo "Do you want to parted ${part} (wait 15s), continue(y/n):"
      read -t 15 answer
      if [[ -n ${answer} && ${answer} = "n" ]]; then
        continue
      fi
    fi

    touch /tmp/part_error.txt
    touch /tmp/part_info.txt

    ${cmd} 2> /tmp/part_error.txt  1> /tmp/part_info.txt

    cmderror=`cat /tmp/part_error.txt`
    if [[ -n  ${cmderror} ]]; then
      echo ${cmderror}
      continue
    fi

    sleep 5
    for i in `seq 1 ${PART_NUMBER}`; do
      mydevice=${part}${i}
      if [[ $part =~ "nvme" ]]; then
        echo "its nvme storage"
        mydevice=${part}p${i}
      fi
      if [[ ${DATA_DISK_TYPE} == "exfat" ]]; then
        cmd="mkfs.exfat ${mydevice}"
      elif [[ ${DATA_DISK_TYPE} == "xfs" ]]; then
        cmd="mkfs.xfs -f -l lazy-count=1 ${mydevice}"
      elif [[ ${DATA_DISK_TYPE} == "ext4" ]]; then
        cmd="mkfs.ext4 -F -O ^has_journal -T largefile ${mydevice} "
      fi
      # echo ${cmd}

      touch /tmp/format_error.txt
      touch /tmp/format_info.txt

      ${cmd} 2>/tmp/format_error.txt 1>/tmp/format_info.txt
      cmderror=`cat /tmp/format_error.txt`
      if [[ -n  ${cmderror} ]]; then
        echo ${cmderror}
        continue
      fi
      AVAILABLE_PARTITIONS[${#AVAILABLE_PARTITIONS[@]}]=${mydevice}
    done
  done
  touch /tmp/available_partitions.result
  echo ${AVAILABLE_PARTITIONS[@]}  > /tmp/available_partitions.result
  echo "parted finished, available partitions: " ${AVAILABLE_PARTITIONS[@]}
}
part_all_disks

# remount
MOUNT_OK="FALSE"
mount_script_name="mount.sh"
need_remount() {
  sataname=`cat ${mount_script_name} | grep $1 | awk '{print $NF}'`
  # echo "sataname: "${sataname}
  mkdir -p ${sataname}
  ${part_device_remount_result}  2> temp
  result=`cat temp`
  if [[ -z ${result} ]]; then
    MOUNT_OK="TRUE"
  fi
  rm -f temp
}

# mount
need_mount() {
  satadisks='/sata*'
  for sata_point in ${satadisks[@]}; do  
    if mountpoint -q ${sata_point}; then
      echo ${sata_point} "has been mounted"
      continue
    fi
    #
    echo "get idle sata point : " ${sata_point}
    # for mulit mount begin
    if lsblk | grep -w ${sata_point}; then
      echo "has mounted by lsblk, then skip ${sata_point}"
      continue
    fi  
    # for mulit mount begin
    mountcmd="${base_mount_cmd} PARTUUID=$1 ${sata_point}"
    echo ${mountcmd}

    rm -rf ${sata_point}/*

    ${mountcmd} 2> temp
    result=`cat temp`
    if [[ -z ${result} ]]; then
      echo ${mountcmd}  >> ${mount_script_name} 
      MOUNT_OK="TRUE"
    else
      echo "mount ${part_device} $1 ${sata_point} failed"
    fi

    rm -f temp
    break
  done
}

# mount disk
mount_disk_device() {
  if [[ ! -f ${mount_script_name} ]]; then
    lsblk -o PARTUUID,MOUNTPOINT | grep sata | awk '{print "'"$base_mount_cmd"'"  " PARTUUID=" $1  "  " $2}'  > ${mount_script_name}
    chmod +x ${mount_script_name}
  fi
  # get root disk 
  get_root_disk
  # do mount operation
  part_device_names=`lsblk -o PARTUUID,KNAME,FSTYPE,SIZE,TYPE,MOUNTPOINT | grep part | grep -v  ${rootdisk}  | grep -v sata   | awk '{system("echo /dev/" $2)}'`
  for part_device in ${part_device_names[@]}; do
    # check fstype
    part_fstype=`lsblk -o FSTYPE  ${part_device}  | grep -v FSTYPE`
    if [[ v${part_fstype} != v${DATA_DISK_TYPE} ]]; then
      echo "${part_device}, ${part_fstype} not expected, skip  "
      continue
    fi
    # check size
    part_device_size=`lsblk -o SIZE  ${part_device} | grep -v SIZE | sed -e 's/G//g'`
    if  expr ${part_device_size} \>  $(( PART_SIZE+2 ))  ||  expr ${part_device_size} \< $(( PART_SIZE-2 )) ; then
      echo "size  ${part_device_size} not expected, skip " ${part_device}
      continue
    fi
    #
    part_device_partuuid=`lsblk -o PARTUUID ${part_device} | grep -v PARTUUID`
    part_device_remount_result=`cat ${mount_script_name} | grep ${part_device_partuuid}`
    if [[ -n  ${part_device_remount_result} ]]; then
      echo "need remount  ${part_device}  ${part_device_partuuid} "
      need_remount ${part_device_partuuid}
    else
      need_mount ${part_device_partuuid}
    fi
    if [[ ${MOUNT_OK} == "FALSE" ]]; then
      echo "mount failed"
    fi
  done
}
mount_disk_device

# generate conf directory
DEST_DIR="/etc/pear/pear_monitor"
create_destination_directory() {
  if [ ! -d ${DEST_DIR} ]; then
    cmdresult=`mkdir -pv ${DEST_DIR} 2>/dev/null`
    if [ -z ${cmdresult} ]; then
      echo "generate ${DEST_DIR} failed"
      exit 1
    fi
  fi
}
create_destination_directory

# get nic
NIC_CONF="${DEST_DIR}/nic.conf"
find_max_speed_netcard() {
  echo "finding proper nic..."
  netcards=`ifconfig | grep RUNNING | grep -v ppp | grep -v veth  | grep MULTICAST | awk '{print $1}' | sed -e 's/://g' | awk -F. '{print $1}' | uniq`
  maxnetcardspeed=0
  for netcard in ${netcards[@]}; do
    netcardspeed=`ethtool ${netcard} 2>/dev/null | grep Speed | awk '{print $2}' | awk -FM '{print $1}'`
    if [[ ${netcardspeed} >  ${maxnetcardspeed}  ]]; then
      maxnetcardspeed=${netcardspeed}
      maxnetcard=${netcard}
    fi
  done
  # echo "maxnetcard " ${maxnetcard} "maxnetcardspeed: " ${maxnetcardspeed}
  if [[ -z ${maxnetcard} ]]; then
     echo  "no available network card "
     return
  fi
  save_nic_result=`echo ${maxnetcard} > ${NIC_CONF}`
  if [ "1${save_nic_result}" != "1" ]; then
    echo "saving ${maxnetcard} failed, error: ${save_nic_result}"
    return
  fi
}
find_max_speed_netcard

# get dev
DEV_CONF="${DEST_DIR}/dev.conf"
find_all_disk_mount_point() {
  echo "finding mounted disk..."
  if [ -f ${DEV_CONF} ]; then
    result=`rm -rf ${DEV_CONF}`
  fi
  for sata in `ls / | grep sata`; do
    save_disk_result=`echo ${sata} >> ${DEV_CONF}`
    if [ "1${save_disk_result}" != "1" ]; then
      echo "saving ${sata} failed, error: ${save_disk_result}"
    fi
  done
}
find_all_disk_mount_point

# download pcdn
NAME="fogvdn_${PLATFORM}_${PCDN_VERSION}.tar.gz"
echo ${NAME}
download_pcdn_installation_file() {
  if [ ! -f ${NAME} ]; then
    echo "downloading ${NAME}..."
    result=`wget https://update.webrtc.win/test/${NAME} 1>/dev/null`
    if [ "1${result}" != "1" ]; then
      echo "download ${NAME} failed, stop"
      exit
    fi
  fi
}
download_pcdn_installation_file

# install pncd
install_pcdn() {
  if [ ! -f ${NAME} ]; then
    echo "unmatched pcdn installation file, stop"
    exit
  fi
  echo "installing pcdn..."
  result=`tar -C / -zxvf ${NAME} 1>/dev/null`
  if [ "1${result}" != "1" ]; then
    echo "install pncd failed, stop"
    exit
  fi
}
install_pcdn

# get mac
fetch_mac_address() {
  echo "getting mac address..."
  result=`/usr/sbin/pear_monitor --auto_mac=2 1>/dev/null`
  if [ "1${result}" != "1" ]; then
    echo "get mac address failed, stop"
    exit
  fi
}
fetch_mac_address

# launch pcdn
/etc/init.d/xc_cdn.sh restart
echo "done"

