#! /usr/bin/python
#
#  Copyright (c) 2009 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin.
#
# This file is part of XtreemFS. XtreemFS is part of XtreemOS, a Linux-based
# Grid Operating System, see <http://www.xtreemos.eu> for more details.
# The XtreemOS project has been developed with the financial support of the
# European Commission's IST program under contract #FP6-033576.
#
# XtreemFS 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.
#
# XtreemFS 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 XtreemFS. If not, see <http://www.gnu.org/licenses/>.
#
#
# AUTHORS: Bjoern Kolbeck (ZIB)
#
import subprocess
import sys
import json
from optparse import OptionParser

spxattr = "xtreemfs.default_sp"

def createCliParser():
    usage = "usage: %prog [options] directory"
    parser = OptionParser(usage=usage)
    parser.add_option("--get",
                      action="store_true", dest="get",
                      help="get the default striping policy")
    parser.add_option("--set",
                      action="store_true", dest="set",
                      help="set the default striping policy")
    parser.add_option("-p", "--striping-policy", dest="policy",
                  help="striping policy", metavar="NONE|RAID0")
    parser.add_option("-s", "--striping-policy-stripe-size", dest="size",
                  help="size of stripes in kB", metavar="n")
    parser.add_option("-w", "--striping-policy-width", dest="width",
                  help="number of OSDs to use", metavar="n")
    parser.add_option("-v","--verbose",
                      action="store_true", dest="verbose",
                      help="print more information")

    return parser;


def doGet(filename, options):
    (success, value) = readxattr(filename,spxattr)
    if (success == False):
        print "error: "+value
        return 1
    else:
        if (value == ""):
            print "no default striping policy set"
            return 2
        else:
            try:
                sp = json.loads(value)
                printSP(filename,sp)
            except ValueError, arg:
                print "cannot decode server response: ",arg
                return 2
            return 0

def doSet(filename, options):
    if (options.size == None or options.width == None or options.policy == None):
        print "must specify polciy, width and size!"
        return 1
    
    tmp = {"pattern":"STRIPING_POLICY_RAID0","width":int(options.width),"size":int(options.size)}
    newsp = json.dumps(tmp);
    (success, error) = setxattr(filename,spxattr,newsp)
    if (success == False):
        print "cannot set striping policy:",error
        return 1
    else:
        print "changed default striping policy for",filename
        if options.verbose:
                printSP(filename,tmp)
        return 0

def printSP(filename,sp):
    print "file:             ",filename
    print "policy:           ",sp['pattern']
    print "stripe-size (kB): ",sp['size']
    print "width:            ",sp['width']

def readxattr(filename, attr):
    cmd = ["getfattr","--absolute-names","--only-values","-n",attr,filename]
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    (out,err) = process.communicate()
    if (process.returncode != 0) or (err != ""):
        return (False, err)
    return (True, out)

def setxattr(filename, attr, value):
    cmd = ["setfattr","-n",attr,"-v",value,filename]
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    (out,err) = process.communicate()
    if (process.returncode != 0) or (err != ""):
        return (False, err)
    return (True, None)

def main(argv):
    parser = createCliParser()
    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("must specify a directory name")
        return 1
    if ( options.get == True ):
        return doGet(args[0],options);
    elif ( options.set == True ):
        return doSet(args[0],options);
    else:
        parser.error("must either specify --get or --set")
        return 1


if __name__ == "__main__":
    returnvalue = main(sys.argv)
    sys.exit(returnvalue)
