#!/usr/bin/env python
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import os,sys
if sys.hexversion<0x2040400:
    sys.stderr.write("pysync.py needs python version at least 2.4.4.\n")
    sys.stderr.write("You are using %s\n"%sys.version)
    sys.stderr.write("Here is a guess at where the python executable is--\n")
    os.system("/bin/sh -c 'type python>&2'");
    sys.exit(1)

import cPickle
import inspect
import hashlib
import signal
import socket
import subprocess
import threading
import zlib
import pysync_remote
from pysync_remote import Options
from pysync_remote import ProgressUpdate, ProgressCounters
from pysync_remote import statToTuple
from gppylib.commands.gp import PySync

# MPP-13617
import re
RE1=re.compile('\\[([^]]+)\\]:(.+)')

bootstrapSource="""
import os,sys
exec(sys.stdin.read(int(sys.stdin.readline())))
"""

class PysyncProxy:
    '''
    The PysyncProxy class is used to initiate a third-party synchronization operation.
    An instance of PysyncProxy is used to start a LocalPysync instance on a remote host
    to be used as the source of the synchronization operation.  The "remote" LocalPysync
    instance then runs RemotePysync on the destination as usual.  Progress information
    is fed from the destination host, through the remote LocalPysync instance an to this
    instance for reporting.
    
    Lines written by LocalPysync to stdout are recorded in the list self.stdout; lines 
    written by LocalPysync to stderr are recorded in self.stderr.  Progress information
    is handled only by the functions set for the recordProgressCallback and 
    recordRawProgressCallback properties.
    '''

    class _Quit(SystemExit):
        def __init__(self, *info):
            SystemExit.__init__(self, *info)

    def __init__(self, sourceHost, sourceDir, destHost, destDir, syncOptions, verbose=False,
                 progressBytes=None, progressTime=None,
                 recordProgressCallback=None, recordRawProgressCallback=None, progressTimestamp=False):
        '''
        Initialize a new PysyncProxy instance.
        
        sourceHost - the host from which data is to be copied.
        sourceDir - the directory on sourceHost from which data is to be copied.
        destHost - the host to which data is to be copied.
        destDir - the directory on sourceHost to which data is to be copied.
        syncOptions - a list of command-line options as described by LocalPysync.usage();
                other options may be added based on the following arguments.
        verbose - indicates whether or not debugging output is generated.
        progressBytes - the number of bytes moved for a volume-based progress message;
                maps to the LocalPysync --progress-bytes option.
        progressTime - the amount of time for a time-based progress message; maps to
                the LocalPysync --progress-time option.
        recordProgressCallback - function to call to present a printable progress
                message generated by RemotePysync; the function must accept a single
                argument of type str.  If not set, progress messages are ignored.
        recordRawProgressCallback - function to call to handle raw progress information
                generated by RemotePysync; the function must accept a single argument
                of type pysync_remote.ProgressUpdate.  If not set, raw progress 
                information is ignored.
        progressTimestamp - indicates whether or not RemotePysync should include the
                observation timestamp on messages it creates.
        '''
        
        self.ppid = 0
        self.sourceHost = sourceHost
        self.sourceDir = sourceDir
        self.destHost = destHost
        self.destDir = destDir
        self.recordProgressCallback = recordProgressCallback
        self.recordRawProgressCallback = recordRawProgressCallback
        
        self.syncOptions = syncOptions
        if verbose:
            self.syncOptions += ["-v"]
        if progressBytes:
            self.syncOptions += ["--progress-bytes", progressBytes]
        if progressTime:
            self.syncOptions += ["--progress-time", progressTime]
        
        self.syncOptions += ["--proxy"]
        if not progressTimestamp:
            self.syncOptions += ["--omit-progress-timestamp"]
            
        self.stderr = []
        self.stdout = []
        self.cmd = None
        self.returncode = None

    def run(self):
        '''
        Initiate and wait for completion of a directory synchronization operation.
        
        Stderr output is appended to the self.stderr list.  Stdout output is appended
        to the self.stdout list.  Progress messages are written to stdout unless a 
        callback is set.
        '''
        
        pysyncCmd = PySync('pysync', self.sourceDir, self.destHost, self.destDir,
                              options=' '.join(self.syncOptions))
        self.cmd = '. %s/greenplum_path.sh && %s' % (os.environ.get('GPHOME'), pysyncCmd.cmdStr)
        
        # save of ppid to allow the process to be stopped.
        self.ppid = os.getppid()
        pidFilename = '/tmp/pysync.py.%s.%s.ppid' % (self.destHost, self.destDir.replace('/', '_'))
        pidFile = open(pidFilename, 'w')
        pidFile.write('%d' % (self.ppid))
        pidFile.close()

        code = 0
        self.p = None
        stderrThread = None
        try:
            try:
                args = []
                args.append("ssh")
                args.extend(["-o", "BatchMode=yes"])
                args.extend(["-o", "StrictHostKeyChecking=no"])
                args.append(self.sourceHost)
                args.append(self.cmd)
                self.p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                stderrThread = ReaderThread("pysync_stderr", self.p.stderr, self.stderr)
                stderrThread.start()
                code = self._work()
            except OSError, e:
                self.stderr.append(str(e))
                raise
        finally:
            os.remove(pidFilename)
            if self.p:
                timer = threading.Timer(2.0, (lambda: os.kill(self.p.pid, signal.SIGHUP)))
                timer.start()
                self.returncode = self.p.wait()
                timer.cancel()
            if stderrThread:
                stderrThread.join(2.0)

        return code

    def _work(self):
        '''
        Wait for and process commands from the LocalPysync instance connected
        to the Popened SSH process.
        
        Command processing continues until EOF is reached on Popen.stdout (the 
        command input stream from LocalPysync) or a "quit" command is proocessed.
        
        Because standard command output may be interleaved with serialized command
        objects, command objects are prefixed with "pKl:<length>\n".  Non-command
        object lines are appended to the self.stdout buffer.
        '''
        while True:
            try:
                # check if parent still alive
                os.kill(self.ppid, 0)
            except:
                # parent gone, exit
                return 2
            
            # Get the length of the next serialized command
            a = self.p.stdout.readline()
            if len(a)==0:
                # End the command loop if EOF
                self.stderr.append("[FATAL]:-Unexpected EOF on LocalPysync output stream")
                return 3
            
            # If not a pickled command object, just record it
            if not a.startswith("pKl:"):
                self.stdout.append(a.rstrip())
                continue
            
            size = int(a[4:])
            
            # Read the serialized command and process it.
            data = self.p.stdout.read(size)
            assert len(data)==size
            try:
                self._doCommand(cPickle.loads(data))
            except PysyncProxy._Quit, e:
                return e.code

    def _doCommand(self,what):
        '''
        Perform the command requested by the remote side and prepare any
        result.
        '''
        if what[0] == 'recordProgress':
            if self.recordProgressCallback:
                self.recordProgressCallback(what[1].rstrip())
            return None
        
        elif what[0] == 'recordRawProgress':
            if self.recordRawProgressCallback:
                self.recordRawProgressCallback(what[1])
            return None
        
        elif what[0]=='quit':
            raise PysyncProxy._Quit(what[1])
        
        else:
            assert 0


class ReaderThread(threading.Thread):
    '''
    Appends all output read from a file handle to the lines buffer.
    '''
    
    def __init__(self, name, file, lines):
        self.file = file
        self.lines = lines
        threading.Thread.__init__(self, name=name)
        self.setDaemon(True)
        
    def run(self):
        for line in self.file:
            self.lines.append(line.rstrip())


class LocalPysync:
    '''
    The LocalPysync class initiates a directory synchronization task by starting
    the pysync_remote module on a target system then processes commands from that
    system to accomplish directry synchronization.  Once the pysync_remote module
    is started on the remote system, this LocalPysync instance acts as the remote
    system's agent.
    
    When invoked through PysyncProxy, stdout is used to return pickled objects
    representing status information from this LocalPysync instance.
    '''

    NUMBER_SCALES = { 'M':1024*1024, 'G':1024*1024*1024, 'T':1024*1024*1024*1024 }

    class _Quit(SystemExit):
        def __init__(self, *info):
            SystemExit.__init__(self, *info)

    def __init__(self, argv, recordProgressCallback=None, recordRawProgressCallback=None, progressTimestamp=False):
        '''
        Initialize a new LocalPysync instance.
        
        argv - a command-line style list of arguments as described by self.usage()
        recordProgressCallback - function to call to present a printable progress
                message generated by RemotePysync; the function must accept a single
                argument of type str.
        recordRawProgressCallback - function to call to handle raw progress information
                generated by RemotePysync; the function must accept a single argument
                of type pysync_remote.ProgressUpdate.
        progressTimestamp - indicates whether or not RemotePysync should include the
                observation timestamp on messages it creates.
        '''

        self.options = Options()
        self.usingProxy = False
        self.sshargs = []
        self.cache = [None]
        self.exclude = set()
        self.include = set()
        self.recordProgressCallback = recordProgressCallback
        if self.recordProgressCallback:
            self.options.sendProgress = True
        self.recordRawProgressCallback = recordRawProgressCallback
        if self.recordRawProgressCallback:
            self.options.sendRawProgress = True
        self.options.progressTimestamp = progressTimestamp
        
        a = argv[1:]
        while a:
            if a[0]=='-v':
                self.options.verbose = True
            
            elif a[0]=='-?':
                self.usage(argv)
            
            elif a[0]=='-compress':
                self.options.compress = True
            
            elif a[0]=='-n':
                self.options.minusn = True
            
            elif a[0]=='--insecure':
                self.options.insecure = True
            
            elif a[0]=='--ssharg':
                a.pop(0)
                self.sshargs.append(a[0])
            
            elif a[0]=='--delete':
                self.options.delete = True
            
            elif a[0]=='-x':
                a.pop(0)
                name = a[0]
                if name[0]=='/':
                    raise Exception('Please do not use absolute path with -x.')
                if name[0:2]!='./':
                    name = os.path.join('.',name)
                self.exclude.add(name)
            
            elif a[0]=='-i':
                a.pop(0)
                name = a[0]
                if name[0]=='/':
                    raise Exception('Please do not use absolute path with -i.')
                if name[0:2]!='./':
                    name = os.path.join('.',name)
                self.include.add(name)

            elif a[0] == '--progress-bytes':
                a.pop(0)
                try:
                    scale = a[0][-1]
                    if scale == '%':
                        # Ensure number part is convertable; otherwise pass the whole value
                        factor = float(a[0][:-1])
                        self.options.progressBytes = a[0]
                    elif scale.upper() in LocalPysync.NUMBER_SCALES:
                        # Real numeric value followed by a supported scale identifier
                        progressBytes = int(float(a[0][:-1]) * LocalPysync.NUMBER_SCALES[scale.upper()])
                        self.options.progressBytes = progressBytes
                    else:
                        # If the value isn't a percent or scaled, it must be an integer number of bytes
                        progressBytes = int(a[0])
                        self.options.progressBytes = self.options.progressBytes
                except ValueError:
                    raise ValueError("--progress-bytes value is not supported", a[0])
                if type(self.options.progressBytes) != str and progressBytes < pysync_remote.SyncProgress.MINIMUM_VOLUME_INTERVAL:
                    raise ValueError("--progress-bytes value must be at least %d" % pysync_remote.SyncProgress.MINIMUM_VOLUME_INTERVAL, a[0])
            
            elif a[0] == '--progress-time':
                a.pop(0)
                try:
                    progressSeconds = int(60 * float(a[0]))
                    self.options.progressTime = progressSeconds
                except ValueError:
                    raise ValueError("--progress-time value is not supported", a[0])
                if progressSeconds < pysync_remote.SyncProgress.MINIMUM_TIME_INTERVAL:
                    raise ValueError("--progress-time value must be at least %f" % (pysync_remote.SyncProgress.MINIMUM_TIME_INTERVAL / 60))
            
            elif a[0] == '--proxy':
                self.usingProxy = True
                self.options.sendProgress = True
                self.recordProgressCallback = self._recordProgress
                self.options.sendRawProgress = True
                self.recordRawProgressCallback = self._recordRawProgress
            
            elif a[0] == '--omit-progress-timestamp':
                self.options.progressTimestamp = False
            
            else:
                break
            a.pop(0)
        if len(a)!=2:
            self.usage(argv)
            
        self.sourceDir = os.path.abspath(a[0])
        if not os.path.exists(self.sourceDir):
            raise ValueError("Source path \"%s\" not found" % self.sourceDir)
        if not os.path.isdir(self.sourceDir):
            raise ValueError("Source path \"%s\" is not a directory" % self.sourceDir)
        if not os.access(self.sourceDir, os.F_OK | os.R_OK | os.X_OK):
            raise ValueError("Source path) \"%s\" is not accessible" % self.sourceDir)
        
        dest = a[1]

        # MPP-13617
        m = re.match(RE1, dest)
        if m:
            self.userAndHost, self.destDir = m.groups()
        else:
            i = dest.find(':')
            if i == -1:
                self.usage(argv)
            self.userAndHost, self.destDir = dest[:i], dest[i+1:]

        self.connectAddress = None
        self.sendData = None
        
        hostname = self.userAndHost[self.userAndHost.find('@')+1:]
        try:
            addrinfo = socket.getaddrinfo(hostname, None)
        except:
            print 'dest>>%s<<' % dest, ' hostname>>%s<<' % hostname
            raise
        
        if addrinfo:
            self.options.addrinfo = addrinfo[0]
        else:
            raise Exception("Unable to determine address for %s" % self.userAndHost)

    def usage(self,argv):
        sys.stderr.write("""usage:
    python """+argv[0]+""" [-v] [-?] [-n] 
                [--ssharg arg] [-x exclude_file] [-i include_file] [--insecure] [--delete]
                [--progress-time seconds] [--progress-bytes { n[.n]{% | G | T} }
                [--proxy] [--omit-progress-timestamp]
                sourcedir [user@]host:destdir
        -v: verbose output
        -?: Print this message.
        --ssharg arg: pass arg to ssh.  Use many times to pass many args.
        -n: Do not do any work. Just print how many bytes will need to be
            transferred over the network per file and a total.
        -x name: Do not transfer named file or directory.  Don't be too
            creative with the name.  For example, "directory/./file" will not
            work--use "directory/file".  Name is relative to sourcedir.
        -i name: Only transfer named file or directory. Don't be too
            creative with the name.  For example, "directory/./file" will not
            work--use "directory/file".  Name is relative to sourcedir.
        --insecure: Do not check MD5 digest after transfering data.
            This makes pysync.py run faster, but a bad guy can forge TCP
            packets and put junk of his choice into your files.
        --delete: Delete things in dst that do not exist in src.
        --progress-time minutes: the number of minutes to elapse before a
            time-based progress message is issued.  Progress messages may
            appear more frequently than specified due to the --progress-bytes 
            value.
        --progress-bytes count:  the number of bytes processed before a
            volume-based progress message is issued.  The count may be a
            number followed by 'G' or 'T' or number followed by '%'.  If
            specified as a percent, the count is calculated as the specified
            percent of the total bytes expected to be processed.
        --proxy: Internal option indicating a call from PysyncProxy.
        --omit-progress-timestamp: Omit the timestamp from progress messages.
""")
        sys.exit(1)

    def readFile(self,filename,offset,size):
        '''
        Read a chunk of the specified size at the specified offset from the
        file identified.  The last chunk read is cached for possible re-reading.
        
        The file is opened only for the duration of the seek and read operations.
        '''
        key = (filename,offset,size)
        if self.cache[0]==key:
            return self.cache[1]
        absfilename = os.path.join(self.sourceDir, filename)
        f = open(absfilename,'rb')
        f.seek(offset)
        a = f.read(size)
        f.close()
        assert len(a)==size
        self.cache = (key,a)
        return a

    def getList(self):
        '''
        Gets a map of {name:stat} pairs to be processed.  The stat value
        is generally the tuple returned from pysync_remote.statToTuple.
        Hard links (an entry with an inode equal to another in the list)
        are represented by a ('L', linked_name) tuple.
        '''
        list = dict()
        inomap = dict()
        for root,dirs,files in os.walk(self.sourceDir):
            for i in dirs+files:
                absname = os.path.join(root, i)
                relname = '.' + absname[len(self.sourceDir):]
                if relname in self.exclude: 
                    if i in dirs:
                        dirs.remove(i)
                    continue
                if len(self.include) > 0:
                   """ Check if the file or dir is in the include list """
                   if relname in self.include:
                      pass
                   else:
                      """ Make sure we include any files or dirs under a dir in the include list."""
                      foundPrefix = False
                      for j in self.include:
                         if relname.startswith(j + '/') == True:
                            foundPrefix = True
                            continue
                      if foundPrefix == False:
                         if i in dirs:
                            dirs.remove(i) 
                         continue

                s = os.lstat(absname)
                if s.st_ino in inomap:
                    list[relname] = ('L',inomap[s.st_ino])
                    continue
                inomap[s.st_ino] = relname
                list[relname] = statToTuple(s,absname)
        return list

    def doCommand(self,what):
        '''
        Perform the command requested by the remote side and prepare any
        result.
        '''
        if what[0]=='connect':
            self.connectAddress = what[1]
        elif what[0]=='getOptions':
            return self.options
        elif what[0]=='getDestDir':
            return self.destDir
        elif what[0]=='getList':
            return self.getList()
        elif what[0]=='getDigest':
            m = hashlib.md5()
            m.update(self.readFile(what[1],what[2],what[3]))
            return m.digest()
        elif what[0]=='getData':
            self.sendData = self.readFile(what[1],what[2],what[3])
            if self.options.compress:
                self.sendData = zlib.compress(self.sendData,1)
            return len(self.sendData)
        elif what[0] == 'recordProgress':
            if self.recordProgressCallback:
                self.recordProgressCallback(what[1].rstrip())
            else:
                sys.stdout.write(what[1].rstrip())
                sys.stdout.write('\n')
            return None
        elif what[0] == 'recordRawProgress':
            if self.recordRawProgressCallback:
                self.recordRawProgressCallback(what[1])
            else:
                sys.stdout.write("raw: " + str(what[1]))
                sys.stdout.write('\n')
            return None
        elif what[0]=='quit':
            raise LocalPysync._Quit(what[1])
        else:
            assert 0


    def _recordProgress(self, message):
        '''
        Send progress information to associated PysyncProxy instance.
        '''
        if message:
            self._sendCommand('recordProgress', message)

    def _recordRawProgress(self, progressUpdate):
        '''
        Send raw progress data to associated PysyncProxy instance.
        '''
        if progressUpdate:
            self._sendCommand('recordRawProgress', progressUpdate)

    def _sendCommand(self, *args):
        '''
        Serialize the command & arguments using cPickle and send write to stdout.
        This method is used for communication with the initiating PysyncProxy 
        instance.
        '''
        a = cPickle.dumps(args)
        sys.stdout.write('pKl:%d\n%s'%(len(a),a))
        sys.stdout.flush()

    def work(self):
        '''
        Wait for and process commands from the RemotePysync instance connected
        to the Popened SSH process.
        
        Command processing continues until EOF is reached on Popen.stdout (the 
        command input stream from RemotePysync) or a "quit" command is proocessed.
        Command response objects are serialized and written to Popen.stdin (the 
        command output stream to RemotePysync).
        '''
        while True:
            try:
                # check if parent still alive
                os.kill(os.getppid(), 0)
            except:
                # parent gone, exit
                return 2
            
            # Get the length of the next serialized command
            a = self.p.stdout.readline()
            if len(a)==0:
                # End the command loop if EOF
                print >> sys.stderr, "[FATAL]:-Unexpected EOF on RemotePysync output stream"
                return 3
            size = int(a)
            
            # Read the serialized command and process it.
            data = self.p.stdout.read(size)
            assert len(data)==size
            try:
                answer = cPickle.dumps(self.doCommand(cPickle.loads(data)))
            except LocalPysync._Quit, e:
                return e.code
            
            # Send the serialized command response
            self.p.stdin.write("%d\n%s"%(len(answer),answer))
            self.p.stdin.flush()
            
            # If the command was a connect order, open a socket to
            # the remote side for data transfer
            if self.connectAddress!=None:
                self.socket = socket.socket(self.options.addrinfo[0])
                self.socket.connect(self.connectAddress)
                self.connectAddress = None
                
            # If the command was a getData order, send the prepared
            # data over the socket.
            if self.sendData!=None:
                self.socket.sendall(self.sendData)
                self.sendData = None

    def run(self):
        '''
        Start the pysync_remote module on the remote host and call self.work() to process 
        commands presented by the remote host.
        '''
        # save of ppid to allow the process to be stopped.
        os.system('echo %d > /tmp/pysync.py.%s.ppid' % (os.getppid(), self.destDir.replace('/', '_')))
        PATH = os.environ.get('PATH') or '.'
        LIBPATH = os.environ.get('LD_LIBRARY_PATH') or '.'
        
        cmd = ('''. %s/greenplum_path.sh && bash -c "python -u -c '%s'"''' 
               % (os.environ.get('GPHOME'),  
                  bootstrapSource))
        args = []
        args.append('ssh')
        args.extend(["-o", "BatchMode=yes"])
        args.extend(["-o", "StrictHostKeyChecking=no"])
        args.extend(self.sshargs)
        args.append(self.userAndHost)
        args.append(cmd)
        code = 0
        self.p = None
        try:
            try:
                pysyncSource = inspect.getsource(pysync_remote)
                self.p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
                self.p.stdin.write("%d\n%s"%(len(pysyncSource),pysyncSource))
                code = self.work()
            except OSError, e:
                sys.stderr.write(str(e))
                raise
        finally:
            os.remove('/tmp/pysync.py.%s.ppid' % (self.destDir.replace('/','_')))
            if self.p:
                timer = threading.Timer(2.0, (lambda: os.kill(self.p.pid, signal.SIGHUP)))
                timer.start()
                rc = self.p.wait()
                timer.cancel()

        if self.usingProxy:
            self._sendCommand('quit', code)
        
        return code

if os.environ.get('GPHOME') is None:
    print >> sys.stderr, '[FATAL]:- Please specify environment variable GPHOME'
    sys.exit(1)

if __name__ == '__main__':
    sys.exit(LocalPysync(sys.argv, progressTimestamp=True).run())
