#!/usr/bin/env python

# Example Usage for local host..
# install/bin/cbcompact 127.0.0.1:12000 compact -b beer-sample 799
#   where 12000 is memcached port and 799 is vbucket id

import clitool
from time import sleep
import sys
import mc_bin_client

def cmd(f):
    """Decorate a function with code to authenticate based on 1-2
    arguments past the normal number of arguments."""

    def g(*args, **kwargs):
        mc = args[0]

        try:
            vbucket = int(args[1])
        except IndexError:
            print "Must specify a vbucket id after the compact argument"
            sys.exit(1)

        n = f.func_code.co_argcount
        if len(args) > n:
            print "Too many args, given %s, but expected a maximum of %s"\
                    % (list(args[1:]), n - 1)
            sys.exit(1)

        bucket = kwargs.get('bucketName', None)
        password = kwargs.get('password', None) or ""
        purgeBeforeTs = long(kwargs.get('purgeBeforeTs', None) or 0)
        purgeBeforeSeq = long(kwargs.get('purgeBeforeSeq', None) or 0)
        dropDeletes = int(kwargs.get('dropDeletes', None) or 0)

        if bucket:
            try:
                mc.sasl_auth_plain(bucket, password)
            except mc_bin_client.MemcachedError:
                print "Authentication error for %s" % bucket
                sys.exit(1)

        f(mc, vbucket, purgeBeforeTs, purgeBeforeSeq, dropDeletes)
    return g

@cmd
def compact(mc, vbucket, purgeBeforeTs, purgeBeforeSeq, dropDeletes):
     try:
        return mc.compact_db(vbucket, purgeBeforeTs, purgeBeforeSeq,
                             dropDeletes)
     except:
         print "Unable to compact vbucket %d with the following parameters "\
               "(purge before time: %d, purge before seqno: %d, drop deletes: "\
               "%d) in requested engine."\
             % (vbucket, purgeBeforeTs, purgeBeforeSeq, dropDeletes)

def main():
    c = clitool.CliTool()

    c.addCommand('compact', compact, 'compact vbucketid')
    c.addOption('-b', 'bucketName',
                'the bucket to perform compaction on (Default: default)')
    c.addOption('-p', 'password', 'the password for the bucket if one exists')
    c.addOption('--purge-before', 'purgeBeforeTs',
                'purge documents before this timestamp')
    c.addOption('--purge-only-upto-seq', 'purgeBeforeSeq',
                'purge only upto this document sequence number')
    c.addFlag('--dropdeletes', 'dropDeletes', 'drop deleted items')

    c.execute()

if __name__ == '__main__':
    main()
