#! /usr/bin/env python
###############################################################################
#                                                                             #
#   Copyright 2005 University of Cambridge Computer Laboratory.               #
#                                                                             #
#   This file is part of Nprobe.                                              #
#                                                                             #
#   Nprobe 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; either version 2 of the License, or         #
#   (at your option) any later version.                                       #
#                                                                             #
#   Nprobe 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 Nprobe; if not, write to the Free Software                     #
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA #
#                                                                             #
###############################################################################


##############################################################################
## 
## 
## Utilities for Nprobe log directories
## 
##
## 

############################################################################ 
############################################################################ 

import string
from sys import argv
import getopt
import os
import re

from sys import exit

import np_warnings
            
############################################################################## 
##############################################################################


CHAN_LABELS = 'ab'

CHANGE_CH_LABELS = 0x1
DEL_DUMPS = 0x2
DEL_ALL_BUT_REPS_AND_DUMPS = 0x4
            
############################################################################## 
##############################################################################

def usage(scriptname):

    print 'usage: %s [-h(elp)] [-v(erbose)] [-D(escend)]\n\t[-c(hange channel labels)] [-d(elete dump files)]\n\t[-A delete all but rep and dump files] PATH' % (scriptname)
    print
    print '\tChange channel labels of form [x].yyy.yyy to X.yyy.yyy'
    print '\tif -descend will descend through tree (root PATH) and apply to all'
    
    exit(1)

##############################################################################

def ch_label(f, v):
    
    nn = os.path.basename(f)
    dir = os.path.dirname(f)
    change = 0
    for lab in CHAN_LABELS:
        lt = len(nn)
        lstr = '[%s]' % lab
        tmp = nn
        if string.find(tmp, lstr) == -1:
            break
        start = 0
        nn = ''
        while start < lt:
            if tmp[start:start+3] == lstr:
                change = 1
                nn += string.upper(lab)
                start += 3
            else:
                nn += tmp[start]
                start += 1

    if change:
        nn = dir + '/' + nn
        if v:
            print '%s -> %s' % (os.path.basename(f), os.path.basename(nn))

        if os.path.isfile(nn):
            change = 0
            q = 'File %s already exists: overwrite? ' % (nn)
            ans = raw_input(q)
            if ans.count('y'):
                change = 1

        if change:
            try:
                os.rename(f, nn)
            except OSError, s:
                print 'FAILED %s' % (s)
            return nn

                

        

##############################################################################
    
def doit(head, a, descend, ops, verb):

    def is_dump_file(f):
	if len(f) >= 11 and f[-10:-4] == ".dump.":
            return 1
        else:
            return 0

    def is_rep_file(f):
	if len(f) >= 10 and f[-9:-4] == ".rep.":
            return 1
        else:
            return 0

    def is_keepfile(f):
        return (re.match('.*lookups.cache.*', f) \
                or re.match('.*server_associations.*', f) \
                or re.match('.*delayed_servers.*', f))
            
    
    for p in a:
        #print a
        if len(head):
            p = head + '/' + p
        if os.path.isfile(p):
            #print p
            exists = 1

            if is_keepfile(p):
                print 'keeping', p
                continue
            
            if is_dump_file(p) and (ops & DEL_DUMPS):
                if verb:
                    #print 'deleting %s' % (os.path.basename(p))
                    print 'deleting %s' % (p)
                try:
                    os.remove(p)
                    exists = 0
                except OSError, s:
                    print 'FAILED %s' % (s)
            
            if not(is_dump_file(p)or is_rep_file(p)) and (ops & DEL_ALL_BUT_REPS_AND_DUMPS):
                if verb:
                    #print 'deleting %s' % (os.path.basename(p))
                    print 'deleting %s' % (p)
                try:
                    os.remove(p)
                    exists = 0
                except OSError, s:
                    print 'FAILED %s' % (s)
                
            if exists and (ops & CHANGE_CH_LABELS):
                ch_label(p, verb)

        if os.path.isdir(p) and (descend or not len(head)):
            if verb:
                print 'dir %s' % (p)
            doit(p, os.listdir(p), descend, ops, verb)
            if (not len(os.listdir(p))) and (ops & DEL_ALL_BUT_REPS_AND_DUMPS):
                if verb:
                    print 'removing directory %s' % (p)
                try:
                    os.rmdir(p)
                except OSError, s:
                    print 'FAILED %s' % (s)
            
    return

##############################################################################
    
def main():

    scriptname = os.path.basename(argv[0])
    verbose = 0
    descend = 0
    ops = 0
    
    try:
        optlist, args = getopt.getopt(argv[1:], 'hvdcDA')

    except getopt.error, s:
        print '%s: %s' % (scriptname, s)
        usage(scriptname)
        exit(1)

    for opt in optlist:
        if opt[0] == '-h':
            usage(scriptname)
        if opt[0] == '-v':
            verbose = 1
        if opt[0] == '-D':
            ans = raw_input('descend? y/n ' )
            if ans.count('y'):
                descend = 1
        if opt[0] == '-d':
            ans = raw_input('delete dump files? y/n ' )
            if ans.count('y'):
                ops += DEL_DUMPS
        if opt[0] == '-c':
            ans = raw_input('change channel labels? y/n ' )
            if ans.count('y'):
                ops += CHANGE_CH_LABELS
        if opt[0] == '-A':
            ans = raw_input('delete all but rep and dump files? y/n ' )
            if ans.count('y'):
                ops += DEL_ALL_BUT_REPS_AND_DUMPS

    if not len(args):
         print '%s - no operational directory' % (scriptname)
         usage(scriptname)

    if ops == 0:
        print 'No ops specified'
        usage(scriptname)
         
    flist = []
    doit('', args, descend, ops, verbose)
    
    return
            
             
##############################################################################


# Call main when run as script
if __name__ == '__main__':
        main()
