# Copyright (C) 2009 Canonical
#
# Authors:
#  Michael Vogt
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 3.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

import logging
import os
import time

from softwarecenter.utils import get_lock, release_lock


class ExpungeCache(object):
    """ Expunge a httplib2 cache dir based on either age of the cache
        file or status of the http data
    """

    def __init__(self, dirs, by_days, by_unsuccessful_http_states,
                 dry_run=False):
        self.dirs = dirs
        # days to keep data in the cache (0 == disabled)
        self.keep_time = 60 * 60 * 24 * by_days
        self.keep_only_http200 = by_unsuccessful_http_states
        self.dry_run = dry_run

    def _rm(self, f):
        if self.dry_run:
            print "Would delete: %s" % f
        else:
            logging.debug("Deleting: %s" % f)
            try:
                os.unlink(f)
            except OSError as e:
                logging.warn("When expunging the cache, could not unlink "
                             "file '%s' (%s)'" % (f, e))

    def _cleanup_dir(self, path):
        """ cleanup the given directory (and subdirectories) using the
            age or http state of the cache
        """
        now = time.time()
        for root, dirs, files in os.walk(path):
            for f in files:
                fullpath = os.path.join(root, f)
                try:
                    header = open(fullpath).readline().strip()
                    if not header.startswith("status:"):
                        logging.debug(
                            "Skipping files with unknown header: '%s'" % f)
                        continue
                    if self.keep_only_http200 and header != "status: 200":
                        self._rm(fullpath)
                    if self.keep_time:
                        mtime = os.path.getmtime(fullpath)
                        logging.debug("mtime of '%s': '%s" % (f, mtime))
                        if (mtime + self.keep_time) < now:
                            self._rm(fullpath)
                except IOError as e:
                    logging.debug("ioerror in cleandir: %s" % e)

    def clean(self):
        # go over the directories
        for d in self.dirs:
            lock = get_lock(os.path.join(d, "expunge.lock"))
            if lock > 0:
                self._cleanup_dir(d)
                release_lock(lock)
            else:
                logging.info("dir '%s' locked by another process" % d)
