#!/usr/bin/python2
# Copyright (c) 2012 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.

"""Clean Staged Images.

This script is responsible for removing older builds from the Chrome OS
devserver. It walks through the files in the images folder, check each found
staged.timestamp and do following.
1. Check if the build target is in the list of targets that need to keep the
   latest build. Skip processing the directory if that's True.
2. Check if the modified time of the timestamp file is older than a given cutoff
   time, e.g., 24 hours before the current time.
3. If that's True, delete the folder containing staged.timestamp.
4. Check if the parent folder of the deleted foler is empty. If that's True,
   delete the parent folder as well. Do so recursively, until it hits the top
   folder, e.g., |~/images|.
"""

import logging
import optparse
import os
import re
import sys
import shutil
import time

# This filename must be kept in sync with devserver's downloader.py
_TIMESTAMP_FILENAME = 'staged.timestamp'
_HOURS_TO_SECONDS = 60 * 60
_EXEMPTED_DIRECTORIES = []

def get_all_timestamp_dirs(root):
    """Get all directories that has timestamp file.

    @param root: The top folder to look for timestamp file.
    @return: An iterator of directories that have timestamp file in it.
    """
    for dir_path, dir_names, file_names in os.walk(root):
        if os.path.basename(dir_path) in _EXEMPTED_DIRECTORIES:
            logging.debug('Skipping %s', dir_path)
            dir_names[:] = []
        elif _TIMESTAMP_FILENAME in file_names:
            dir_names[:] = []
            yield dir_path


def file_is_too_old(build_path, max_age_hours):
    """Test to see if the build at |build_path| is older than |max_age_hours|.

    @param build_path: The path to the build (ie. 'build_dir/R21-2035.0.0')
    @param max_age_hours: The maximum allowed age of a build in hours.
    @return: True if the build is older than |max_age_hours|, False otherwise.
    """
    cutoff = time.time() - max_age_hours * _HOURS_TO_SECONDS
    timestamp_path = os.path.join(build_path, _TIMESTAMP_FILENAME)
    if os.path.exists(timestamp_path):
        age = os.stat(timestamp_path).st_mtime
        if age < cutoff:
            return True
    return False


def try_delete_parent_dir(path, root):
    """Try to delete parent directory if it's empty.

    Recursively attempt to delete parent directory of given path. Only stop if:
    1. parent directory is the root directory used to stage images.
    2. The base name of given path is a valid build path, e.g., R31-4532.0.0 or
       4530.0.0 (for builds staged in *-channel/[platform]/).
    3. The parent directory is not empty.

    @param path: Start path that attempt to delete whose parent directory.
    @param root: root directory that devserver used to stage images, e.g.,
                 |/usr/local/google/home/dshi/images|, must be an absolute path.
    """
    pattern = '(\d+\.\d+\.\d+)'
    match = re.search(pattern, os.path.basename(path))
    if match:
        return

    parent_dir = os.path.abspath(os.path.join(path, os.pardir))
    if parent_dir == root:
        return

    try:
        os.rmdir(parent_dir)
        try_delete_parent_dir(parent_dir, root)
    except OSError:
        pass


def prune_builds(builds_dir, keep_duration, keep_paladin_duration):
    """Prune the build dirs and also delete old labels.

    @param builds_dir: The builds dir where all builds are staged.
      on the chromeos-devserver this is ~chromeos-test/images/
    @param keep_duration: How old of regular builds to keep around.
    @param keep_paladin_duration: How old of Paladin builds to keep around.
    """
    for timestamp_dir in get_all_timestamp_dirs(builds_dir):
        logging.debug('Processing %s', timestamp_dir)
        if '-paladin/' in timestamp_dir:
            keep = keep_paladin_duration
        else:
            keep = keep_duration
        if file_is_too_old(timestamp_dir, keep):
            logging.debug('Deleting %s', timestamp_dir)
            shutil.rmtree(timestamp_dir)
            # Resursively delete parent folders
            try_delete_parent_dir(timestamp_dir, builds_dir)


def main():
    """Main routine."""
    usage = 'usage: %prog [options] images_dir'
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('-a', '--max-age', default=24, type=int,
                      help='Number of hours to keep normal builds: %default')
    parser.add_option('-p', '--max-paladin-age', default=24, type=int,
                      help='Number of hours to keep paladin builds: %default')
    parser.add_option('-v', '--verbose',
                      dest='verbose', action='store_true', default=False,
                      help='Run in verbose mode')
    options, args = parser.parse_args()
    if len(args) != 1:
        parser.print_usage()
        sys.exit(1)

    builds_dir = os.path.abspath(args[0])
    if not os.path.exists(builds_dir):
        logging.error('Builds dir %s does not exist', builds_dir)
        sys.exit(1)

    if options.verbose:
        logging.getLogger().setLevel(logging.DEBUG)
    else:
        logging.getLogger().setLevel(logging.INFO)

    prune_builds(builds_dir, options.max_age, options.max_paladin_age)


if __name__ == '__main__':
    main()
