#!/bin/bash

export LANG="zh_CN.UTF-8"
IFS=$'\n'

#  $1名称 $2裁剪长度    根据裁剪长度适度调整，保证不出现中文乱码
function fix_zh {
	tmp_value=`echo "$1" | cut -b -$2`
	num1=`echo "$tmp_value" | wc -c`
	num2=`echo "$tmp_value" | wc -m`
	odd_even=$(expr $num1 - $num2)
	
	if [ `expr $odd_even % 2` -eq 0 ];then
		tmp_value1=`echo "$1" | cut -b -$(expr $2 - 2)`
		num3=`echo "$tmp_value1" | wc -m`
		if [ "$num2" = "$num3" ];then
			tmp_value="${tmp_value1}"
		fi
	else
		tmp_value=`echo "$1" | cut -b -$(expr $2 - 1)`
	fi
}

#更新名称在所在列不重名覆盖。 返回值有：$parent_child和$new_name
function update_new_name {
	n=0
	while true; do
		if [ $n -eq 0 ];then
			if [ $j -eq 0 ];then
				parent_child="${new_name}"
			else
				parent_child="${matrix1[$i,$[ $j - 1 ]]}/$new_name"
			fi
		
		else
			if [ $ext_exist -eq 0 ];then
				#--------------------文件无后缀------------------------- 
				fix_zh "$new_name" "$(expr $(echo -n "$new_name" | wc -c) - $(echo -n "($n)" | wc -c))"
				new_name="$tmp_value($n)"
			else
				#--------------------文件有后缀-------------------------
				fix_zh "$tmp_value" "$(expr $(echo -n "$tmp_value" | wc -c) - $(echo -n "($n)" | wc -c))"
				new_name="$tmp_value($n)${ext}"
			fi
			
			if [ $j -eq 0 ];then
				parent_child="${new_name}"
			else
				parent_child="${matrix1[$i,$[ $j - 1 ]]}/$new_name"
			fi
		fi
		((n++))
		[[ -n "${save_arr[${parent_child}]}" ]] || break
	done
}

function fix_255 {
	for (( j=0; j<$max_col; j++ ))
	do
		#关联数组save_arr记录每一列（级）的路径名称 例如save_arr[0]记录第一列（级）的路径名称
		declare -A save_arr
		for (( i=0; i<max_row; i++ )); do
            if [ -z ${matrix2[$i,$j]} ] ;then
                continue
            fi
        	save_arr[${matrix2[$i,$j]}]=$i
        done

		#关联数组flag_name记录每一列（级）处理过的路径
		declare -A flag_name
		for (( i=0; i<$max_row; i++ ))
		do
			if [ -z "${matrix[$i,$j]}" ] || [ $(echo -n "${matrix[$i,$j]}" | wc -c) -lt 255 ];then
				continue
			fi
			if [ $j -eq 0 ];then
				[[ -n "${flag_name[${matrix1[$i,$j]}]}" ]] && continue
			else
				[[ -n "${flag_name["${matrix1[$i,$[ $j - 1]]}/${matrix1[$i,$j]}"]}" ]] && continue
			fi
	
			ext_exist=0
			if [ "${matrix[$i,$[ $j + 1 ]]}" != "|" ] ;then	
				#---------处理文件夹-----
				new_name=`echo -n "${matrix1[$i,$j]}" | cut -b -255`
				fix_zh "$new_name" "255"
				new_name="$tmp_value"
			else 
				#---------处理文件,分后缀是否存在-----
				ext=${matrix[$i,$j]##*.}
				if [ "$ext" != "${matrix1[$i,$j]}" ];then
					ext=".${ext}"
					ext_exist=1
				fi
				
				ext_length=`echo "$ext" | wc -c`
				if [ $ext_length -gt 255 ];then
					fix_zh "$ext" "255"
					new_name="$tmp_value"
				else
					num=$(expr 256 - $ext_length)
					fix_zh "${matrix1[$i,$j]}" "$num"
					new_name="$tmp_value"
					new_name="${new_name}${ext}"
				fi
			fi
	
			if [ $j -eq 0 ];then
				parent_child="${new_name}"
			else
				parent_child="${matrix1[$i,$[ $j - 1 ]]}/$new_name"
			fi
			
			[[ -n "${save_arr[${parent_child}]}" ]] && update_new_name

			#将同一个文件夹(父子路径均相同)统一重命名。k==j时，本文件(夹)重命名。
			for (( k=0; k<$max_row; k++));do
				if [ $j -eq 0 ];then
					if [ "${matrix1[$i,$j]}" = "${matrix1[$k,$j]}" ];then
						matrix[$k,$j]=$new_name
					fi
				else
					if [ "${matrix1[$i,$[ $j - 1 ]]}" = "${matrix1[$k,$[ $j - 1 ]]}" ] && [ "${matrix1[$i,$j]}" = "${matrix1[$k,$j]}" ];then
						matrix[$k,$j]=$new_name
					fi
				fi
			done

			save_arr[${parent_child}]=$j

			if [ $j -eq 0 ];then
				flag_name[${matrix1[$i,$j]}]=$j
			else
				flag_name["${matrix1[$i,$[ $j - 1]]}/${matrix1[$i,$j]}"]=$j
			fi
		done

		unset save_arr
		unset flag_name
	done
}

if [ $# -ne 2 ];then
	n=0
	for param in "$@"
	do
		if [ $n -eq 0 ] || [ $n -eq 1 ];then
			n=$[ $n + 1 ] 
			continue
		fi

		i=1
		while((1==1))
		do
			re=$(echo $param | grep "/")
			if [ "$re" = "" ];then
				if [ -z "$(7z l $1  $param | awk '{print $3}'| grep "D..")" ];then
					array[ $(expr $i - 1) ]=$param
					array[ $i ]="|"
					break
				else
					array[ $(expr $i - 1) ]=$param
					array[ $i ]="/"
					break
				fi
			fi

			splitchar=`echo $param|cut -d "/" -f$i`
			if [ "$splitchar" != "" ];then
				   array[ $(expr $i - 1) ]=$splitchar
				   ((i++))
			else
				if [ -z "$(7z l $1  $param | awk '{print $3}'| grep "D..")" ];then
					   array[ $(expr $i - 1) ]="|"
				else
					   array[ $(expr $i - 1) ]="/"
				fi
				break
		   fi
		done
		
		arr[$n]="${array[*]}"
		unset array
		n=$[ $n + 1 ]
	done

	declare -A matrix
	declare -A matrix1
	declare -A matrix2
	
	max_row=0
	max_col=0
	for i in "${arr[@]}"; do
		brr=($i)
		
		if [ ${#brr[*]} -gt $max_col ];then
			max_col=${#brr[*]}
		fi
	
		for j in "${!brr[@]}"; do
			matrix[$max_row,$j]=${brr[$j]}
			matrix1[$max_row,$j]=${brr[$j]}
			if [ $j -eq 0 ]; then
				matrix2[$max_row,$j]=${brr[$j]}
			else
				if [ -n ${brr[$j]} ];then
					if [ "${brr[$j]}" = "|" ] || [ "${brr[$j]}" = "/" ];then
						continue
					else
						matrix2[$max_row,$j]="${brr[$[ $j - 1]]}/${brr[$j]}"
					fi		
				fi
			fi
		done
		max_row=$[ $max_row + 1 ]
	done
	
	fix_255
	for (( i=0; i<$max_row; i++ ))
	do
		old_folder=""
		new_folder=""
		for (( j=0; j<$max_col; j++))
		do
			if [ "${matrix[$i,$j]}" = "|" ] ;then
				   break
			fi
			
			if [ "${matrix[$i,$j]}" = "/" ] ;then
				if [ "$2" = "dest_dir" ];then
					zip_path=`dirname "$1"`
					mkdir -p "$zip_path/$new_folder"
				else
					mkdir -p "$2/$new_folder"	
				fi
				break
			fi
			new_folder="$new_folder${matrix[$i,$j]}/"
			old_folder="$old_folder${matrix1[$i,$j]}/"
		done				   
	done

	for (( i=0; i<$max_row; i++ ))
	do
		old_file=""
		new_file=""
		for (( j=0; j<$max_col; j++))
		do
			if [ "${matrix[$i,$j]}" = "|" ] ;then
				old_file=${old_file::-1}
				new_file=${new_file::-1}

				if [ "$2" = "dest_dir" ];then
					zip_path=`dirname "$1"`
					myfolder=`dirname "$zip_path/$new_file"`
					if [ ! -d $myfolder ]; then
						new_file_name=`echo "$new_file" | sed 's/.*\///'`
						7z x "$1" "$old_file" -so > "$zip_path/$new_file_name"
					else
						7z x "$1" "$old_file" -so > "$zip_path/$new_file"
					fi
				else
					myfolder=`dirname "$2/$new_file"`
					if [ ! -d $myfolder ]; then
						new_file_name=`echo "$new_file" | sed 's/.*\///'`
						7z x "$1" "$old_file" -so > "$2/$new_file_name"
					else
						7z x "$1" "$old_file" -so > "$2/$new_file"
					fi
				fi
				break
			fi
			
			if [ "${matrix[$i,$j]}" = "/" ] ;then
				break
			fi

			old_file="$old_file${matrix1[$i,$j]}/"
			new_file="$new_file${matrix[$i,$j]}/"
		done
	done

else
	zip_name=`echo "$1" | sed 's/.*\///'`
	if [ "$2" = "dest_dir" ];then
		zip_path=`dirname "$1"`
	else
		zip_path="$2"
	fi

	mkdir -p $zip_path	
	awk_script='{
		if (ix == 0) {
			ix = index($0,"Name");  
		}
		p = (body == 1);
		if (ix > 0) {
			body = (body + ($0 ~ /-------------------\ -----\ ------------\ ------------\ \ ------------------------/)) % 2;
		}
		if (p == 1 && body == 1) {
			print substr($0, ix);
		}
	}'
	dirfiles=`7z l "$1" | awk '$3 ~ /^D/{print $0"/"} $3 !~ /^D/{print $0}'| awk "$awk_script"`
	

	time=$(date +%H%M%S)
	mkdir -p "/tmp/.fr_$time/"
	7z x -bd -y -o"/tmp/.fr_$time/" -- $1 > /dev/null 2>&1	
	cd "/tmp/.fr_$time/"
	cp -r . "$zip_path/"
	rm -rf "/tmp/.fr_$time/"

	i=0
	long_flag=0
	for df in `echo "$dirfiles"`
	do
		#echo "df--$df"
		j=0
		while((1==1))
		do
			re=$(echo $df | grep "/")
			if [ "$re" = "" ];then
				if [ $(echo -n "$df" | wc -c) -gt 252 ];then
					long_flag=1
					array[0]=$df
					array[1]="|"
				fi
				break
			fi
	
			splitchar=$(echo $df|cut -d "/" -f$(expr $j + 1))
			if [ "$splitchar" != "" ];then
				if [ $(echo -n "$splitchar" | wc -c) -gt 252 ];then
					long_flag=1
				fi
				array[$j]=$splitchar
				((j++))
			else
				if [ "${df: -1}" = "/" ];then
					array[$j]="/"
				else
					array[$j]="|"
				fi
				break
			fi
		done
	
		if [ $long_flag -eq 1 ];then
			arr[$i]="${array[*]}"
			unset array
			long_flag=0
		fi
		((i++))
	done

	#matrix用来修改的文件列表  matrix1记录修改前的文件列表 matrix2父子目录拼接成新串的文件列表
	declare -A matrix
	declare -A matrix1
	declare -A matrix2
	
	max_row=0
	max_col=0
	for i in "${arr[@]}"; do
		brr=($i)
		
		if [ ${#brr[*]} -gt $max_col ];then
			max_col=${#brr[*]}
		fi
	
		for j in "${!brr[@]}"; do
			matrix[$max_row,$j]=${brr[$j]}
			matrix1[$max_row,$j]=${brr[$j]}
			if [ $j -eq 0 ]; then
				matrix2[$max_row,$j]=${brr[$j]}
			else
				if [ -n ${brr[$j]} ];then
					if [ "${brr[$j]}" = "|" ] || [ "${brr[$j]}" = "/" ];then
						continue
					else
						matrix2[$max_row,$j]="${brr[$[ $j - 1]]}/${brr[$j]}"
					fi		
				fi
			fi
		done
		max_row=$[ $max_row + 1 ]
	done
	
	fix_255
	for (( i=0; i<$max_row; i++ ))
	do
		old_folder=""
		new_folder=""
		for (( j=0; j<$max_col; j++))
		do
			if [ "${matrix[$i,$j]}" = "|" ] ;then
				break
			fi
			
			if [ "${matrix[$i,$j]}" = "/" ] ;then
				echo "$new_folder" >>path
				break
			fi
			new_folder="$new_folder${matrix[$i,$j]}/"
			old_folder="$old_folder${matrix1[$i,$j]}/"
		done
	done

	xargs -d '\n' mkdir -p -- < path
	rm -rf path
	for (( i=0; i<$max_row; i++ ))
	do
		old_file=""
		new_file=""
		for (( j=0; j<$max_col; j++))
		do
			if [ "${matrix[$i,$j]}" = "|" ] ;then
				old_file=${old_file::-1}
				new_file=${new_file::-1}
				7z x "$1" "$old_file" -so > "$zip_path/$new_file"
				break
			fi
			old_file="$old_file${matrix1[$i,$j]}/"
			new_file="$new_file${matrix[$i,$j]}/"
		done
	done
fi

exit 0
