#!/system/bin/sh

SYSDIR=/cache
LOGDIR=$SYSDIR/logs
BINDIR=/system/bin
LAST_KMSG_FILE=/proc/last_kmsg
DEBUGFS_PATH=/sys/kernel/debug
SMEM_DEBUGFS_PATH=$DEBUGFS_PATH/smem_log
SMEM_GLOBAL_PATH=/proc/smem_global
INTERVAL_MAIN=30

function debug()
{
    echo $1
    #echo $1 >>$LOGDIR/getlogdebug.txt
    
}

function bak_if()
{
  local bakfile=$1
  local file=${bakfile##*/}
  local dir=${bakfile%/*}
  local size=$2

  debug "bakfile:$bakfile file:$file dir:$dir size:$size"
  if busybox [ ! -f $bakfile ] ; then
      debug "bakfile:$bakfile donot exist"
      return
  fi
  
  l=`busybox du -s   $bakfile | busybox awk '{print $1}'`
  if busybox [ "$l" -gt "$2" ] ;then
    debug "rm $bakfile.0.tar.gz"
    rm $bakfile.0.tar.gz
    pwd
    debug "cd $dir"
    cd $dir
    debug "$file -> $file.0.tar.gz"
    busybox tar zcf $file.0.tar.gz $file
    debug "rm $file"
    rm $file
    cd -
    pwd
  fi
}

function process_info()
{
        debug "process_info begin"
	echo "------------------------------------------" >> $LOGDIR/logcat/ps.txt
	date >> $LOGDIR/logcat/ps.txt
	ps | busybox grep "system_server" >> $LOGDIR/logcat/ps.txt
  	top -m 8 -t -n 1 >> $LOGDIR/logcat/ps.txt
  	top -m 4 -s rss -n 1 >> $LOGDIR/logcat/ps.txt 
  	busybox sed -n '1,4'p /proc/meminfo >> $LOGDIR/logcat/ps.txt

  	bak_if  $LOGDIR/logcat/ps.txt 4096
	debug "process_info end"
}

function backup_traces()
{
        debug "backup_traces begin"
	#busybox cp -f /data/anr/traces* $LOGDIR/logcat/
	#busybox rm -f /data/anr/traces*

	local tf
	local tt=`date +%G%m%d_%H%M%S`
	for  tf in  `ls /data/anr/traces*`
	do
	    local file=${tf##*/}
	    #debug "cp -f ${tf} $LOGDIR/logcat/${tt}_${file}"
	    #busybox cp -f ${tf} $LOGDIR/logcat/${tt}_${file}
	    debug "busybox tar zcf $LOGDIR/logcat/${tt}_${file}.tar.gz ${tf}"
	    busybox tar zcf $LOGDIR/logcat/${tt}_${file}.tar.gz ${tf}
	done
	busybox rm -f /data/anr/traces*
	debug "backup_traces end"
}


function kmsg()
{
        debug "kmsg begin"
	dmesg -c >> $LOGDIR/kernel/log_kernel.txt
	bak_if  $LOGDIR/kernel/log_kernel.txt 4096
	debug "kmsg end"
}

function bakup_tombstones()
{
#backup tombstones
debug "backup_tombstones begin"
  ls /data/tombstones/* >/dev/null
  case "$?" in
      0) echo "has tombstones"
         cd $SYSDIR
         $BINDIR/busybox tar czf $LOGDIR/logcat/tomb.tar.gz logs/logcat/tomb*
         busybox cp -r /data/tombstones/tombstone* $LOGDIR/logcat/
#         rm -r /data/tombstones/tombstone*
  ;;
  esac
debug "backup_tombstones end"
}

function ps_info()
{
	echo "########################<<ps -t information>>########################" >> $LOGDIR/logcat/ps.txt
      	ps -t >> $LOGDIR/logcat/ps.txt
      	echo "#####################################################################" >> $LOGDIR/logcat/ps.txt
}

function packages_info()
{
      	pm list packages > $LOGDIR/logcat/installedapp.txt
	cat /data/system/packages.xml > $LOGDIR/logcat/packages.xml
}

function baseinfo()
{
    echo "Service getlog Started:" >> $LOGDIR/logcat/baseinfo.txt
    uptime >>  $LOGDIR/logcat/baseinfo.txt
    date >> $LOGDIR/logcat/baseinfo.txt
    cat /proc/uptime  >> $LOGDIR/logcat/baseinfo.txt
    echo "========================================" >> $LOGDIR/logcat/baseinfo.txt
    echo "Kernel Version:" >> $LOGDIR/logcat/baseinfo.txt
    cat /proc/version >> $LOGDIR/logcat/baseinfo.txt
    cat /proc/cmdline >> $LOGDIR/logcat/baseinfo.txt
    echo "========================================" >> $LOGDIR/logcat/baseinfo.txt
    echo "Memory Info:" >> $LOGDIR/logcat/baseinfo.txt
    cat /proc/meminfo >> $LOGDIR/logcat/baseinfo.txt
    echo "========================================" >> $LOGDIR/logcat/baseinfo.txt
    echo "Property:" >> $LOGDIR/logcat/baseinfo.txt
    getprop  >> $LOGDIR/logcat/baseinfo.txt
}

function autorun()
{
    if busybox [ ! -d /system/bin/autorun ]
    then
	return
    fi
    #/system/bin/autorun.sh&
    
    #echo $$ >/dev/cpuctl/apps/bg_non_interactive/tasks

     scripts=`ls /system/bin/autorun`

     for exe in $scripts
     do
 	debug "run $exe"
 	/system/bin/autorun/${exe}>>/cache/logs/logcat/${exe}-log.txt 2>&1 &
     done
}

function logcat_to_file()
{
    logcat -b system -f $LOGDIR/logcat/logcat_system.txt -r10240 -n4 -v threadtime *:D &
    logcat -b main -f $LOGDIR/logcat/logcat_main.txt -r10240 -n4 -v threadtime *:D &
    logcat -b radio -f $LOGDIR/logcat/logcat_radio.txt -r10240 -n8 -v time *:D &
    logcat -b events -f $LOGDIR/logcat/logcat_events.txt -r4096 -n4 -v threadtime *:D &
}

function save_reset_log()
{
    date > $LOGDIR/resetlog/kernel_resetlog.txt
    cat $LAST_KMSG_FILE >> $LOGDIR/resetlog/kernel_resetlog.txt
    cat $SMEM_DEBUGFS_PATH/dump_sym > $LOGDIR/resetlog/smem_log_event.txt
    cat $SMEM_DEBUGFS_PATH/dump_static_sym > $LOGDIR/resetlog/smem_log_static_events.txt
    cat $SMEM_DEBUGFS_PATH/dump_power_sym > $LOGDIR/resetlog/smem_log_power_events.txt
    cat $DEBUGFS_PATH/smd/modem_err > $LOGDIR/resetlog/smd.txt
    cat $SMEM_DEBUGFS_PATH/dump_voters > $LOGDIR/resetlog/voters.txt
}

function checkfd()
{
    local l=`countfd | busybox sort -n -r  | busybox awk  '{if(NR==1){print $1}}'`
    debug "countfd $l"
    if busybox [ "$l" -ge "900" ] ;then
	local pid=`countfd | busybox sort -n -r  | busybox awk  '{if(NR==1){print $3}}'`
	debug "$pid has open $l files"
	if busybox [ ! -f "$LOGDIR/logcat/$pid.txt" ] ; then
	    debug "countfd > $LOGDIR/logcat/$pid.txt"
	    date >> $LOGDIR/logcat/$pid.txt
	    countfd | busybox sort -n -r > $LOGDIR/logcat/$pid.txt
	    dumpsys >> $LOGDIR/logcat/dumpsys.txt &
	else
	    debug "$LOGDIR/logcat/$pid.txt exist"
	fi
    fi
}

function procrank_collect()
{
    bak_if  $LOGDIR/logcat/memory.txt 4096
    date >> $LOGDIR/logcat/memory.txt
    cat /proc/meminfo >> $LOGDIR/logcat/memory.txt
    cat /sys/fs/selinux/enforce | grep 0
    if busybox [ "$?" -eq "0" ] ;then
	procrank >> $LOGDIR/logcat/memory.txt &
    fi
}

function mainloop()
{
        debug "mainloop begin"
	local interval=0
	local e
	local next
	chmod 744 /data/system/dropbox/*
	chmod 744 $LOGDIR/logcat/dropbox/*

	#process_info
	#kmsg
	#bakup_tombstones
	for e in ${crontab[@]}
	do
	    eval next=\${${e}[0]}
	    eval interval=\${${e}[1]}
	    debug "cur:$e $next $interval $sys_uptime"
	    if busybox [ "$sys_uptime" -ge "$next" ] ;then
		interval=`busybox expr $interval + $sys_uptime`
		eval ${e}[0]=\$interval
		eval next=\${${e}[0]}
		debug "next:$next $interval $sys_uptime"
		eval local len=\${#${e}[@]}
		local funi=2
		while [ $funi -lt $len ]
		do
		    eval \${${e}[$funi]}
		    eval debug \${${e}[$funi]}
		    funi=`busybox expr $funi + 1`
		done
	    fi
	done
	chmod 755 $LOGDIR/logcat 
  	chmod -R 755  $LOGDIR/logcat/*
	chmod -R 755  $LOGDIR/kernel/*

	debug "mainloop end"
}

function need_log
{
    local available=`busybox df  | grep "$SYSDIR" | busybox awk '{print $3}'`
    local total=`busybox du -s $LOGDIR | busybox awk '{print $1}'`
    #debug "need_log $available $total"
    if busybox [ "$available" -gt "51200" -a "$total" -lt "122880" ] ;then
	return 0
    fi
    return 1
}

function delete_logs_low
{
    
    available=`busybox df  | grep "$SYSDIR" | busybox awk '{print $3}'`
    
    if busybox [ "$available" -lt "51200" ] ;then
	debug "$SYSDIR to low: $available, delete some log"
    	rm -rf $LOGDIR/bugreports
	rm -rf $LOGDIR/Pictures
	rm $LOGDIR/loglast[2-9]*.gz
	rm $LOGDIR/*.hprof
    fi

    if busybox [ "$available" -lt "20480" ] ;then
	debug "$LOGDIR to low: $available, delete *hprof *.gz"
	rm $LOGDIR/*.hprof
	rm $LOGDIR/*.gz
    fi
}


function onboot()
{

    debug "onboot"
	if busybox [ "$isbootcomplete" -eq "1" ] ;then
	    return
	fi
	local bootanim_service=`getprop init.svc.bootanim`
	if busybox [ "$bootanim_service" != "stopped" ] ;then
	    debug "bootanim service $bootanim_service"
	    return
	fi
	isbootcomplete=1
	for func in ${onbootcomplete[@]}
	do
	    debug "call $func when bootcomplete"
	    $func
	done
}

function save_bootlog()
{
    debug "save bootlog"
    $BINDIR/busybox tar czf $LOGDIR/logcat/logsboot0.tar.gz $LOGDIR/kernel $LOGDIR/logcat
}



function call_at()
{
    local which
    local when
    local fun
    for which in ${crontab_at[*]}
    do
	eval when=\${${which}[0]}
	eval fun=\${${which}[1]}
	if busybox [ "$when" -ne "0" ] ; then
	    debug "$fun will call at $when"
	fi
	
	if busybox [ "$when" -ne "0" -a "$sys_uptime" -ge "$when" ] ; then
	    $fun
	    eval ${which}[0]=0
	fi
    done
}


every30s=(0 29  kmsg)
every60s=(0 59 process_info bakup_tombstones backup_traces)
every600s=(0 599 checkfd procrank_collect)
crontab=(every30s every60s every600s)
onbootcomplete=(baseinfo ps_info packages_info autorun)
bootlog=(180 save_bootlog)
crontab_at=(bootlog)
isbootcomplete=0


mkdir $LOGDIR
mkdir $LOGDIR/kernel
mkdir $LOGDIR/logcat
mkdir $LOGDIR/smem
mkdir $LOGDIR/resetlog

if busybox [ ! -L "/data/local/logs" ] ; then
    ln -s $LOGDIR /data/local/logs
fi



cd $SYSDIR
mv $LOGDIR/loglast4.tar.gz $LOGDIR/loglast5.tar.gz
mv $LOGDIR/loglast3.tar.gz $LOGDIR/loglast4.tar.gz
mv $LOGDIR/loglast2.tar.gz $LOGDIR/loglast3.tar.gz
mv $LOGDIR/loglast1.tar.gz $LOGDIR/loglast2.tar.gz
date > $LOGDIR/kernel/ram_console.txt
cat $LAST_KMSG_FILE >> $LOGDIR/kernel/ram_console.txt
busybox tar czf $LOGDIR/loglast1.tar.gz logs/kernel logs/logcat logs/smem logs/resetlog logs/smem*.gz
   
rm -r logs/kernel/*
rm -r logs/logcat/*
rm -r logs/smem/*
rm -r logs/resetlog/*
rm -r logs/smem*.tar.gz
rm -r logs/*.txt

chown system.root $LOGDIR/logcat/
$BINDIR/busybox chmod -R 755 $LOGDIR/
chmod 755 /data/system/dropbox
mkdir $LOGDIR/logcat/dropbox
chown system.root $LOGDIR/logcat/dropbox
chmod 755 $LOGDIR/logcat/dropbox


mount -t debugfs none $DEBUGFS_PATH


save_reset_log
logcat_to_file

sys_uptime=$INTERVAL_MAIN

while true
do	

    uptime0=`cat /proc/uptime | busybox awk '{print $1}'`
    uptime0=${uptime0/\.*/}

    debug "time: $sys_uptime"    

    onboot
    call_at

    if need_log ; then
	mainloop
    else
	debug "donot log"
    fi
    delete_logs_low
    uptime1=`cat /proc/uptime | busybox awk '{print $1}'`
    uptime1=${uptime1/\.*/}
    sec=`busybox expr $uptime0 + $INTERVAL_MAIN - $uptime1`
    if busybox [ "$sec" -gt "30" -o  "$sec" -le "0" ] ;then
	debug "sec error $sec, reset it"
	sec=$INTERVAL_MAIN
    fi
    debug "need to sleep $sec"
    sleep $sec
    sys_uptime=`busybox expr $sys_uptime + $INTERVAL_MAIN`
done
