#!/usr/bin/env python

# Copyright (c) 2014 Pivotal Software, Inc. All Rights Reserved
#
# This software contains the intellectual property of Pivotal Software, Inc.
# or is licensed to Pivotal Software, Inc. from third parties. Use of this
# software and the intellectual property contained therein is expressly
# limited to the terms and conditions of the License Agreement under which
# it is provided by or on behalf of Pivotal Software, Inc.

from gppylib.mainUtils import simple_main,  addStandardLoggingAndHelpOptions, addMasterDirectoryOptionForSingleClusterProgram
from optparse import Option, OptionGroup, OptionParser, OptionValueError

import re
import stat
import sys

try:
    import gppylib
    import gppylib.operations.backup_utils as backup_utils
    from datetime import datetime
    from gppylib import gplog
    from gppylib import pgconf
    from gppylib import userinput
    from gppylib.commands.base import Command
    from gppylib.gpparseopts import OptParser, OptChecker
    from gppylib.operations import Operation
    from gppylib.operations.persistent_rebuild import RebuildPersistentTables, DEFAULT_BATCH_SIZE
    from gppylib.operations.utils import DEFAULT_NUM_WORKERS
    from gppylib.gparray import GpArray
    from gppylib.db import dbconn
    from getpass import getpass
    import gppylib.operations.backup_utils
except ImportError, e:
    sys.exit('Cannot import modules.  Please check that you have sourced greenplum_path.sh.  Detail: ' + str(e))
 
logger = gplog.get_default_logger()

MAX_BATCH_SIZE = 64
MIN_BATCH_SIZE = 1 
EXECNAME = 'gppersistentrebuild'
GPPERSISTENTREBUILD_PID_FILE = 'gppersistentrebuild.pid'

class GpPersistentRebuild(Operation):
    def __init__(self, options, args):
        self.contentid_file = options.contentid_file
        self.content_id = options.content_id
        self.backup = options.backup
        self.restore = options.restore
        self.batch_size = options.batch_size
        self.backup_dir = options.backup_dir

    def run(self):
        if not self.batch_size:
            self.batch_size = DEFAULT_BATCH_SIZE

        if self.batch_size > MAX_BATCH_SIZE:
            raise Exception('Maximum batch size allowed is 64')

        if self.batch_size < MIN_BATCH_SIZE:
            raise Exception('Minimum batch size allowed is 1')

        if self.backup and self.restore:
            raise Exception(' --backup cannot be used with --restore option')

        if not self.contentid_file and not self.content_id:
            raise Exception(' Neither --content-id nor contentid-file provided. Please specify one of them')

        if self.contentid_file and self.content_id:
            raise Exception(' --content-id cannot be used with --contentid-file provided. Please specify only one of them')

        RebuildPersistentTables(contentid_file=self.contentid_file,
                                content_id=self.content_id,
                                backup=self.backup,
                                restore=self.restore,
                                batch_size=self.batch_size,
                                backup_dir=self.backup_dir).run()
       
        return 0
        
def create_parser():
    parser = OptParser(option_class=OptChecker, 
                       version='%prog version $Revision: #5 $',
                       description='Rebuild persistent tables')

    addStandardLoggingAndHelpOptions(parser, includeNonInteractiveOption=False)

    addTo = OptionGroup(parser, 'Persistent tables rebuild options')
    addTo.add_option('-f', '--contentid-file', metavar="<filename>",
                     help="File containing content ids for segments where persistent tables need to be rebuilt")
    addTo.add_option('-c', '--content-id', metavar="<comma separated list of content ids>",
                     help="Segment content id for the segment where persisten tables need to be rebuilt")
    addTo.add_option('-b', '--backup', action='store_true',
                     help="Only Backup the persistent table files and do not perform the persistent table rebuild")
    addTo.add_option('-r', '--restore', metavar="<timestamp of the backup to be restored>",
                     help="Restore the backup corresponding to the specified timestamp")
    addTo.add_option('-B', '--batch-size', metavar='<batch size>', type="int",
                     help="Batch size for Worker pool")
    addTo.add_option('-D', '--backup-dir', metavar="<backup directory>",
                     help="Backup directory for persistent tables and transaction logs on segment host")
    parser.add_option_group(addTo)

    parser.setHelp([
    """
    This tool is used to rebuild persistent tables.
    """
    ])

    return parser

if __name__ == '__main__':
    sys.argv[0] = EXECNAME                                                                       # for cli_help
    simple_main(create_parser, GpPersistentRebuild, { "pidfilename" : GPPERSISTENTREBUILD_PID_FILE,
                                                      "programNameOverride" : EXECNAME })        # for logger
