#!/bin/sh

# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This script should be called daily to clean up log files.

. /usr/share/cros/disk_utils.sh

CLEANUP_PAUSED_FILE="/var/lib/cleanup_logs_paused"
NUM_DAYS_TO_PRESERVE=7
# Threshold for additional histogram reporting (in 1KB blocks), 1GB in total.
ADDITIONAL_REPORTING_THRESHOLD_BLOCKS=1048576
SHADOW="/home/.shadow"

# Paths for the CRX cache. Shared with installer/crx-import.conf
UNVALIDATED_CRX_CACHE=${STATEFUL}/unencrypted/import_extensions
VALIDATED_CRX_CACHE=/var/cache/external_cache

report_additional_statistics() {
  # Number of users on device.
  local user_count="$(find $SHADOW -maxdepth 1 -mindepth  1 -type d | wc -l)"
  metrics_client -s Platform.DiskUsage.UsersOnDevice "${user_count}"

  # Handle case when there are no users on device.
  if [ "${user_count}" -le 0 ]; then
    return 0
  fi

  local users_category=${user_count}Users
  if [ "${user_count}" -eq 1 ]; then
    users_category=1User
  fi
  if [ "${user_count}" -ge 7 ]; then
    users_category=7OrMoreUsers
  fi

  local stats
  local sum_and_max_prog='{ sum += $1;
                            if (max < $1) max = $1;
                          }
                          END { print sum, max }'
  # All pass-through directories.
  for dir in Cache Downloads GCache; do
    # Calculate sum and maximum over all user_count for each directory.
    stats=$(du -sk $SHADOW/*/vault/user/$dir 2> /dev/null |
            awk "${sum_and_max_prog}")
    metrics_client Platform.DiskUsage.${dir}_Max.${users_category} \
                   ${stats##* } $METRICS_ARGS
    # Since disk usage is several orders higher that number of users, it is safe
    # to use integer division here.
    metrics_client Platform.DiskUsage.${dir}_Avg.${users_category} \
                   $(( ${stats%% *} / ${user_count} )) $METRICS_ARGS
  done

  # Report days since the least frequently used account signed in.
  # It is split over user_count, and is reported upon low disk space to provide
  # input information for cleanup tuning.

  local least_used_days=$(cryptohome --action=dump_last_activity |
                          awk '$2 > max {max = $2} END {print max}')

  metrics_client Platform.DiskUsage.LeastUsedAccountDays.${users_category} \
                 ${least_used_days} $METRICS_ARGS
}

remove_old_dated_files() {
  find "$1" -name "$2" -mtime +${NUM_DAYS_TO_PRESERVE} -exec rm '{}' ';'
}

rotate_file() {
  local file="$1"
  if [ ! -f "${file}" ]; then
    # Avoid creating an empty file if it does not exist to begin with
    return
  fi
  local basename="${file%%.*}"
  local extension="${file#*.}"
  if [ "${basename}" = "${extension}" ]; then
    extension=""
  else
    extension=".${extension}"
  fi
  echo Rotating "${file}"
  for i in $(seq ${NUM_DAYS_TO_PRESERVE} -1 2); do
    mv -f "${basename}.$((i - 1))${extension}" "${basename}.$i${extension}"
  done
  mv -f "${basename}${extension}" "${basename}.1${extension}"
  touch "${basename}${extension}"
}

rotate_logs() {
  echo Rotating rsyslogd logs
  for x in messages secure net.log faillog session_manager; do
    rotate_file "/var/log/${x}"
  done
  chown syslog /var/log/messages /var/log/secure /var/log/net.log
  sudo pkill -HUP rsyslogd
}

# Wipe the unencyrpted CRX cache if it still exists.
wipe_crx_cache() {
  # If we are on removable media or we haven't imported the crx cache,
  # don't wipe.
  local root_dev="$(basename "$(rootdev -s -d)")"
  local removable="$(cat "/sys/block/${root_dev}/removable")" || :
  local disk_percent="$(get_stateful_usage_percent)" || :
  [ -z "${disk_percent}" ] && disk_percent=0
  if [ ${removable:-0} -eq 0 ] && [ -d "${UNVALIDATED_CRX_CACHE}" ] && \
      [ -f "${VALIDATED_CRX_CACHE}/.initialized" ] && \
      [ ${disk_percent} -gt 25 ]; then
    echo "Wiping unvalidated crx cache as it has already been imported."
    rm -rf "${UNVALIDATED_CRX_CACHE}"
  fi
}

if [ -r "${CLEANUP_PAUSED_FILE}" ]; then
  echo "Exiting early because ${CLEANUP_PAUSED_FILE} exists."
  exit 1
fi

# Remove old chrome logs (not logged in)
remove_old_dated_files /var/log/chrome "chrome_*-*"

# Remove old chrome logs (logged in)
remove_old_dated_files /home/chronos/user/log "chrome_*-*"

# Remove old miscellaneous UI logs
remove_old_dated_files /var/log/ui "ui.*-*"

# Remove old update engine logs
remove_old_dated_files /var/log/update_engine "update_engine.*-*"

# Remove old power manager logs
remove_old_dated_files /var/log/power_manager "power*"

# Rotate other logs
rotate_logs

# Report disk usage statistics
METRICS_ARGS="0 1073741824 50"
metrics_client Platform.DiskUsageVar \
               $(du -sxk /var/ | awk '{print $1}') $METRICS_ARGS
metrics_client Platform.DiskUsageChronos \
               $(du -sxk /home/chronos | awk '{print $1}') $METRICS_ARGS

# Report overall stateful usage.
metrics_client -e Platform.StatefulUsage "$(get_stateful_usage_percent)" 101

NUMBER_OF_USERS=$(ls /home/user/ | wc -l)
metrics_client Platform.DiskUsage.NumUserHomeDirectories \
               $NUMBER_OF_USERS 1 50 50

WEEKLY_USERS_ACTIVE=$(cryptohome --action=dump_last_activity |
                      awk '$2 <= 7 {++count} END {print count}')
metrics_client -s Login.UsersActiveWeekly ${WEEKLY_USERS_ACTIVE}

if [ $NUMBER_OF_USERS -gt 0 ] ; then
  metrics_client -s Login.UsersActiveWeekly.Percent \
                 $(($WEEKLY_USERS_ACTIVE * 100 / $NUMBER_OF_USERS))
else
  metrics_client -s Login.UsersActiveWeekly.Percent 0
fi

# Report days since the least frequently used account signed in.
# It is reported every time to measure effect of autodeletion feature.
DAYS_SINCE_LFU_ACCOUNT_SIGNIN=$(cryptohome --action=dump_last_activity |
                                awk '$2 > max {max = $2} END {print max}')

# Check if there are any users.
if [ "${DAYS_SINCE_LFU_ACCOUNT_SIGNIN}" != "" ]; then
  metrics_client Login.LeastUsedAccountDays \
                 $DAYS_SINCE_LFU_ACCOUNT_SIGNIN 1 90 90
fi

# Report additional metrics if we are low on free space.
if [ "$(get_stateful_free_space_blocks)" -le \
     "$ADDITIONAL_REPORTING_THRESHOLD_BLOCKS" ] ; then
  report_additional_statistics
fi

wipe_crx_cache
