#!/usr/bin/python
#
# imageminimizer: removes files on the filesystem
#
# Copyright 2007, Red Hat  Inc.
#
# 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 2 of the License.
#
# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import glob
import optparse
import os
import shutil
import sys

class ImageMinimizer:
    filename = ''
    dryrun = False
    prefix = None
    keeps = set()
    drops = set()
    visited = set()
    
    def __init__(self, filename, root, dryrun):
        self.filename = filename
        self.prefix = root
        self.dryrun = dryrun
        
    # Recursively adds all files and directories.
    # This is done becuase globbing does not allow
    # ** for arbitrary nesting.
    def add_directory(self, files, dirname):
        self.visited.add(dirname)
        for root, dirs, items in os.walk(dirname):
            for dir in dirs:
                self.visited.add(os.path.join(root, dir))
            for name in items:
                files.add(os.path.join(root, name))
            
    def add_pattern(self, files, pattern):
        globs = glob.glob(pattern)
        for g in globs:
            if os.path.isdir(g):
                self.add_directory(files, g)
            else:
                files.add(g)

    # Parses each line in the ifle
    def parse_line(self, line):
        tup = line.partition(' ')
        command = tup[0].lower()
        pattern = tup[2].strip()
        if not self.prefix == None:
            pattern = pattern.lstrip('/')
            pattern = os.path.join(self.prefix, pattern)

        # Strip out all the comments and blank lines
        if not (command.startswith('#') or command==''):
            if command == 'keep':
                self.add_pattern(self.keeps, pattern)
            elif command == 'drop':
                self.add_pattern(self.drops, pattern)
            else:
                raise Exception ('Unknown Command: ' + command)

    def remove(self, files):
        for tag in sorted(files, reverse=True):
            self.visited.add(os.path.split(tag)[0])
            if os.path.isdir(tag):
                self.visited.add(tag)
            else:
                if self.dryrun:
                    print 'rm ' + tag
                else:
                    #print 'rm ' + tag
                    os.remove(tag)
                    
        #remove all empty directory. Every 8k counts!
        for dir in sorted(self.visited, reverse=True):
            if len(os.listdir(dir)) == 0:
                if self.dryrun:                
                    print 'rm -rf ' + dir  
                else:
                    #print 'rm -rf ' + dir 
                    os.rmdir(dir)     
        
    def filter(self):
        for line in (open(self.filename).readlines()):
            self.parse_line(line.strip())
        final = self.drops.difference(self.keeps)
        self.remove(final)


def parse_options(args):
    usage = "usage: %prog [options] filename"
    parser = optparse.OptionParser(usage=usage)
    parser.set_defaults(root=os.environ.get('INSTALL_ROOT'), dry_run=False)
    
    parser.add_option("-i", "--installroot", type="string", dest="root",
        help="Root path to prepend to all patterns. Defaults to INSTALL_ROOT")
        
    parser.add_option("--dryrun", action="store_true", dest="dryrun",
        help="If set, no filesystem changes are made.")        
        
    #imgcreate.setup_logging(parser)
    
    return parser.parse_args()
       

if __name__ == "__main__":
    try:
        (options, args) = parse_options(sys.argv[1:])
        filename = args[0]
        minimizer = ImageMinimizer(filename, options.root, options.dryrun)
        minimizer.filter()
    except SystemExit, e:
        sys.exit(e.code)
    except KeyboardInterrupt, e:
        print >> sys.stderr, _("Aborted at user request")
    except Exception, e:
        print e
        sys.exit(1)
