#!/usr/bin/python2
# $Id: dpm-disk-to-dpns,v 1.1 2008/10/21 08:47:05 gcowan Exp $

__author__ = 'Greig A Cowan'
__date__ = 'May 2008'
__version = 0.3

'''
Prints out the physical file names of all files on a pool, server and
filesystem.
'''

import sys
try:
    import dpm
except:
    print 'Failed to import dpm API. Check your $PYTHONPATH. If this is correct, Please check the bitness of your system libraries - it may be that you have 64bit python and 32bit DPM.'
    sys.exit(1)
import os

from optparse import OptionParser

def main():
#    $ gridpp_dpm_disk_to_dpns -f pool1.glite.ecdf.ed.ac.uk:/grid01/path/to/file
    usage = '''usage: %prog [options]

    Find the mappings between the files on a pool
    and the LFN in the DPNS namespace. If you want to analyse all
    server:filesytems on a pool, you can use the -p option. i.e.,

    $ gridpp_dpm_disk_to_dpns -p poolname

    To restrict to a particular server:filesystem combination, use the -s
    option. i.e.,

    $ gridpp_dpm_disk_to_dpns -s pool1.glite.ecdf.ed.ac.uk:/grid01
    '''

    parser = OptionParser(
        usage = usage)
    parser.add_option('-d', '--debug', dest='debug', action='store_true',
                      help='Use debug flag only for testing.')
    parser.add_option('-s','--serverfs',dest='serverfs',
                      help='Specify which server:filesystem to be analysed.')
    parser.add_option('-p','--pool',dest='pool',
                      help='Specify which pool to be analysed.')
#    parser.add_option('-f','--file',dest='pfn',
#                      help='Specify the PFN that you want to map to DPNS.')

    (options, args) = parser.parse_args()

    if len(args) > 0:
        parser.error("ERROR: Incorrect number of arguments")

    if (not options.pool) and (not options.serverfs):
        print 'ERROR: You must specify a pool or server:fs to analyse'
        parser.print_help()
        sys.exit(1)

    if options.pool and options.serverfs:
        print 'WARNING: You specified both a pool and a server:fs. Ignoring pool.'

    DPNS_HOST = os.environ['DPNS_HOST']

    server = ''
    filesystem = ''

    result, dpm_pools = dpm.dpm_getpools()
    if result != 0:
        print 'ERROR: Could not get the list of pools from DPM.'
        sys.exit(1)

    pools = {}
    fs_2_process = []

    for pool in dpm_pools:
        result, dpm_fs = dpm.dpm_getpoolfs(pool.poolname)
        if result != 0:
            print 'ERROR: Could not get the list of filesystems from DPM.'
            sys.exit(1)
        for fs in dpm_fs:
            if pools.has_key(pool.poolname):
                pools[pool.poolname].append([fs.server, fs.fs])
            else:
                pools[pool.poolname] = [[fs.server, fs.fs]]

    if options.pool:
        if options.pool in pools.keys():
            fs_2_process = pools[options.pool]
            pool = options.pool
        else:
            print 'ERROR: Pool %s does not exist' % options.pool
            sys.exit(1)

    user_defined_serverfs = False
    if options.serverfs:
        for POOL, values in pools.iteritems():
            for serverfs in values:
                if serverfs == options.serverfs.split(':'):
                    fs_2_process = [serverfs]
                    pool = POOL
                    user_defined_serverfs = True

        if not user_defined_serverfs:
            print 'ERROR: server:fs combination does not exist',\
                  options.serverfs
            sys.exit(1)

    listp = dpm.dpns_list()
    flag = dpm.CNS_LIST_BEGIN

#   if options.pfn:
#        res = dpm.dpns_listreplicax(pool, server, fs, flag, listp)

    for server, fs in fs_2_process:
        if options.debug:
            print "Analysing", server + ':' + fs
        flag = dpm.CNS_LIST_BEGIN
        while(1):
            res = dpm.dpns_listreplicax( pool, server, fs, flag, listp)
            flag = dpm.CNS_LIST_CONTINUE

            if res == None:
                break
            else:
                rep_name = res.sfn

            buf = ''
            for i in range(0,dpm.CA_MAXPATHLEN+1):
                buf=buf + ' '

            dpm.dpns_getpath( DPNS_HOST, res.fileid, buf)

            print res.sfn, buf.rstrip()

        dpm.dpns_listreplicax(pool, server, fs, dpm.CNS_LIST_END,listp)


if __name__ == '__main__':
         main()
