"""Tag the sandbox for release, make source and doc tarballs.

Requires Python 2.6

Example of invocation (use to test the script):
python makerelease.py --platform=msvc6,msvc71,msvc80,msvc90,mingw -ublep 0.6.0 0.7.0-dev

When testing this script:
python makerelease.py --force --retag --platform=msvc6,msvc71,msvc80,mingw -ublep test-0.6.0 test-0.6.1-dev

Example of invocation when doing a release:
python makerelease.py 0.5.0 0.6.0-dev

Note: This was for Subversion. Now that we are in GitHub, we do not
need to build versioned tarballs anymore, so makerelease.py is defunct.
"""
from __future__ import print_function
import os.path
import subprocess
import sys
import doxybuild
import subprocess
import xml.etree.ElementTree as ElementTree
import shutil
import urllib2
import tempfile
import os
import time
from devtools import antglob, fixeol, tarball
import amalgamate

SVN_ROOT = 'https://jsoncpp.svn.sourceforge.net/svnroot/jsoncpp/'
SVN_TAG_ROOT = SVN_ROOT + 'tags/jsoncpp'
SCONS_LOCAL_URL = 'http://sourceforge.net/projects/scons/files/scons-local/1.2.0/scons-local-1.2.0.tar.gz/download'
SOURCEFORGE_PROJECT = 'jsoncpp'

def set_version( version ):
    with open('version','wb') as f:
        f.write( version.strip() )

def rmdir_if_exist( dir_path ):
    if os.path.isdir( dir_path ):
        shutil.rmtree( dir_path )

class SVNError(Exception):
    pass

def svn_command( command, *args ):
    cmd = ['svn', '--non-interactive', command] + list(args)
    print('Running:', ' '.join( cmd ))
    process = subprocess.Popen( cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT )
    stdout = process.communicate()[0]
    if process.returncode:
        error = SVNError( 'SVN command failed:\n' + stdout )
        error.returncode = process.returncode
        raise error
    return stdout

def check_no_pending_commit():
    """Checks that there is no pending commit in the sandbox."""
    stdout = svn_command( 'status', '--xml' )
    etree = ElementTree.fromstring( stdout )
    msg = []
    for entry in etree.getiterator( 'entry' ):
        path = entry.get('path')
        status = entry.find('wc-status').get('item')
        if status != 'unversioned' and path != 'version':
            msg.append( 'File "%s" has pending change (status="%s")' % (path, status) )
    if msg:
        msg.insert(0, 'Pending change to commit found in sandbox. Commit them first!' )
    return '\n'.join( msg )

def svn_join_url( base_url, suffix ):
    if not base_url.endswith('/'):
        base_url += '/'
    if suffix.startswith('/'):
        suffix = suffix[1:]
    return base_url + suffix

def svn_check_if_tag_exist( tag_url ):
    """Checks if a tag exist.
    Returns: True if the tag exist, False otherwise.
    """
    try:
        list_stdout = svn_command( 'list', tag_url )
    except SVNError as e:
        if e.returncode != 1 or not str(e).find('tag_url'):
            raise e
        # otherwise ignore error, meaning tag does not exist
        return False
    return True

def svn_commit( message ):
    """Commit the sandbox, providing the specified comment.
    """
    svn_command( 'ci', '-m', message )

def svn_tag_sandbox( tag_url, message ):
    """Makes a tag based on the sandbox revisions.
    """
    svn_command( 'copy', '-m', message, '.', tag_url )

def svn_remove_tag( tag_url, message ):
    """Removes an existing tag.
    """
    svn_command( 'delete', '-m', message, tag_url )

def svn_export( tag_url, export_dir ):
    """Exports the tag_url revision to export_dir.
       Target directory, including its parent is created if it does not exist.
       If the directory export_dir exist, it is deleted before export proceed.
    """
    rmdir_if_exist( export_dir )
    svn_command( 'export', tag_url, export_dir )

def fix_sources_eol( dist_dir ):
    """Set file EOL for tarball distribution.
    """
    print('Preparing exported source file EOL for distribution...')
    prune_dirs = antglob.prune_dirs + 'scons-local* ./build* ./libs ./dist'
    win_sources = antglob.glob( dist_dir, 
        includes = '**/*.sln **/*.vcproj',
        prune_dirs = prune_dirs )
    unix_sources = antglob.glob( dist_dir,
        includes = '''**/*.h **/*.cpp **/*.inl **/*.txt **/*.dox **/*.py **/*.html **/*.in
        sconscript *.json *.expected AUTHORS LICENSE''',
        excludes = antglob.default_excludes + 'scons.py sconsign.py scons-*',
        prune_dirs = prune_dirs )
    for path in win_sources:
        fixeol.fix_source_eol( path, is_dry_run = False, verbose = True, eol = '\r\n' )
    for path in unix_sources:
        fixeol.fix_source_eol( path, is_dry_run = False, verbose = True, eol = '\n' )

def download( url, target_path ):
    """Download file represented by url to target_path.
    """
    f = urllib2.urlopen( url )
    try:
        data = f.read()
    finally:
        f.close()
    fout = open( target_path, 'wb' )
    try:
        fout.write( data )
    finally:
        fout.close()

def check_compile( distcheck_top_dir, platform ):
    cmd = [sys.executable, 'scons.py', 'platform=%s' % platform, 'check']
    print('Running:', ' '.join( cmd ))
    log_path = os.path.join( distcheck_top_dir, 'build-%s.log' % platform )
    flog = open( log_path, 'wb' )
    try:
        process = subprocess.Popen( cmd,
                                    stdout=flog,
                                    stderr=subprocess.STDOUT,
                                    cwd=distcheck_top_dir )
        stdout = process.communicate()[0]
        status = (process.returncode == 0)
    finally:
        flog.close()
    return (status, log_path)

def write_tempfile( content, **kwargs ):
    fd, path = tempfile.mkstemp( **kwargs )
    f = os.fdopen( fd, 'wt' )
    try:
        f.write( content )
    finally:
        f.close()
    return path

class SFTPError(Exception):
    pass

def run_sftp_batch( userhost, sftp, batch, retry=0 ):
    path = write_tempfile( batch, suffix='.sftp', text=True )
    # psftp -agent -C blep,jsoncpp@web.sourceforge.net -batch -b batch.sftp -bc
    cmd = [sftp, '-agent', '-C', '-batch', '-b', path, '-bc', userhost]
    error = None
    for retry_index in range(0, max(1,retry)):
        heading = retry_index == 0 and 'Running:' or 'Retrying:'
        print(heading, ' '.join( cmd ))
        process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
        stdout = process.communicate()[0]
        if process.returncode != 0:
            error = SFTPError( 'SFTP batch failed:\n' + stdout )
        else:
            break
    if error:
        raise error
    return stdout

def sourceforge_web_synchro( sourceforge_project, doc_dir,
                             user=None, sftp='sftp' ):
    """Notes: does not synchronize sub-directory of doc-dir.
    """
    userhost = '%s,%s@web.sourceforge.net' % (user, sourceforge_project)
    stdout = run_sftp_batch( userhost, sftp, """
cd htdocs
dir
exit
""" )
    existing_paths = set()
    collect = 0
    for line in stdout.split('\n'):
        line = line.strip()
        if not collect and line.endswith('> dir'):
            collect = True
        elif collect and line.endswith('> exit'):
            break
        elif collect == 1:
            collect = 2
        elif collect == 2:
            path = line.strip().split()[-1:]
            if path and path[0] not in ('.', '..'):
                existing_paths.add( path[0] )
    upload_paths = set( [os.path.basename(p) for p in antglob.glob( doc_dir )] )
    paths_to_remove = existing_paths - upload_paths
    if paths_to_remove:
        print('Removing the following file from web:')
        print('\n'.join( paths_to_remove ))
        stdout = run_sftp_batch( userhost, sftp, """cd htdocs
rm %s
exit""" % ' '.join(paths_to_remove) )
    print('Uploading %d files:' % len(upload_paths))
    batch_size = 10
    upload_paths = list(upload_paths)
    start_time = time.time()
    for index in range(0,len(upload_paths),batch_size):
        paths = upload_paths[index:index+batch_size]
        file_per_sec = (time.time() - start_time) / (index+1)
        remaining_files = len(upload_paths) - index
        remaining_sec = file_per_sec * remaining_files
        print('%d/%d, ETA=%.1fs' % (index+1, len(upload_paths), remaining_sec))
        run_sftp_batch( userhost, sftp, """cd htdocs
lcd %s
mput %s
exit""" % (doc_dir, ' '.join(paths) ), retry=3 )

def sourceforge_release_tarball( sourceforge_project, paths, user=None, sftp='sftp' ):
    userhost = '%s,%s@frs.sourceforge.net' % (user, sourceforge_project)
    run_sftp_batch( userhost, sftp, """
mput %s
exit
""" % (' '.join(paths),) )


def main():
    usage = """%prog release_version next_dev_version
Update 'version' file to release_version and commit.
Generates the document tarball.
Tags the sandbox revision with release_version.
Update 'version' file to next_dev_version and commit.

Performs an svn export of tag release version, and build a source tarball.    

Must be started in the project top directory.

Warning: --force should only be used when developping/testing the release script.
"""
    from optparse import OptionParser
    parser = OptionParser(usage=usage)
    parser.allow_interspersed_args = False
    parser.add_option('--dot', dest="dot_path", action='store', default=doxybuild.find_program('dot'),
        help="""Path to GraphViz dot tool. Must be full qualified path. [Default: %default]""")
    parser.add_option('--doxygen', dest="doxygen_path", action='store', default=doxybuild.find_program('doxygen'),
        help="""Path to Doxygen tool. [Default: %default]""")
    parser.add_option('--force', dest="ignore_pending_commit", action='store_true', default=False,
        help="""Ignore pending commit. [Default: %default]""")
    parser.add_option('--retag', dest="retag_release", action='store_true', default=False,
        help="""Overwrite release existing tag if it exist. [Default: %default]""")
    parser.add_option('-p', '--platforms', dest="platforms", action='store', default='',
        help="""Comma separated list of platform passed to scons for build check.""")
    parser.add_option('--no-test', dest="no_test", action='store_true', default=False,
        help="""Skips build check.""")
    parser.add_option('--no-web', dest="no_web", action='store_true', default=False,
        help="""Do not update web site.""")
    parser.add_option('-u', '--upload-user', dest="user", action='store',
                      help="""Sourceforge user for SFTP documentation upload.""")
    parser.add_option('--sftp', dest='sftp', action='store', default=doxybuild.find_program('psftp', 'sftp'),
                      help="""Path of the SFTP compatible binary used to upload the documentation.""")
    parser.enable_interspersed_args()
    options, args = parser.parse_args()

    if len(args) != 2:
        parser.error( 'release_version missing on command-line.' )
    release_version = args[0]
    next_version = args[1]

    if not options.platforms and not options.no_test:
        parser.error( 'You must specify either --platform or --no-test option.' )

    if options.ignore_pending_commit:
        msg = ''
    else:
        msg = check_no_pending_commit()
    if not msg:
        print('Setting version to', release_version)
        set_version( release_version )
        svn_commit( 'Release ' + release_version )
        tag_url = svn_join_url( SVN_TAG_ROOT, release_version )
        if svn_check_if_tag_exist( tag_url ):
            if options.retag_release:
                svn_remove_tag( tag_url, 'Overwriting previous tag' )
            else:
                print('Aborting, tag %s already exist. Use --retag to overwrite it!' % tag_url)
                sys.exit( 1 )
        svn_tag_sandbox( tag_url, 'Release ' + release_version )

        print('Generated doxygen document...')
##        doc_dirname = r'jsoncpp-api-html-0.5.0'
##        doc_tarball_path = r'e:\prg\vc\Lib\jsoncpp-trunk\dist\jsoncpp-api-html-0.5.0.tar.gz'
        doc_tarball_path, doc_dirname = doxybuild.build_doc( options, make_release=True )
        doc_distcheck_dir = 'dist/doccheck'
        tarball.decompress( doc_tarball_path, doc_distcheck_dir )
        doc_distcheck_top_dir = os.path.join( doc_distcheck_dir, doc_dirname )
        
        export_dir = 'dist/export'
        svn_export( tag_url, export_dir )
        fix_sources_eol( export_dir )
        
        source_dir = 'jsoncpp-src-' + release_version
        source_tarball_path = 'dist/%s.tar.gz' % source_dir
        print('Generating source tarball to', source_tarball_path)
        tarball.make_tarball( source_tarball_path, [export_dir], export_dir, prefix_dir=source_dir )

        amalgamation_tarball_path = 'dist/%s-amalgamation.tar.gz' % source_dir
        print('Generating amalgamation source tarball to', amalgamation_tarball_path)
        amalgamation_dir = 'dist/amalgamation'
        amalgamate.amalgamate_source( export_dir, '%s/jsoncpp.cpp' % amalgamation_dir, 'json/json.h' )
        amalgamation_source_dir = 'jsoncpp-src-amalgamation' + release_version
        tarball.make_tarball( amalgamation_tarball_path, [amalgamation_dir],
                              amalgamation_dir, prefix_dir=amalgamation_source_dir )

        # Decompress source tarball, download and install scons-local
        distcheck_dir = 'dist/distcheck'
        distcheck_top_dir = distcheck_dir + '/' + source_dir
        print('Decompressing source tarball to', distcheck_dir)
        rmdir_if_exist( distcheck_dir )
        tarball.decompress( source_tarball_path, distcheck_dir )
        scons_local_path = 'dist/scons-local.tar.gz'
        print('Downloading scons-local to', scons_local_path)
        download( SCONS_LOCAL_URL, scons_local_path )
        print('Decompressing scons-local to', distcheck_top_dir)
        tarball.decompress( scons_local_path, distcheck_top_dir )

        # Run compilation
        print('Compiling decompressed tarball')
        all_build_status = True
        for platform in options.platforms.split(','):
            print('Testing platform:', platform)
            build_status, log_path = check_compile( distcheck_top_dir, platform )
            print('see build log:', log_path)
            print(build_status and '=> ok' or '=> FAILED')
            all_build_status = all_build_status and build_status
        if not build_status:
            print('Testing failed on at least one platform, aborting...')
            svn_remove_tag( tag_url, 'Removing tag due to failed testing' )
            sys.exit(1)
        if options.user:
            if not options.no_web:
                print('Uploading documentation using user', options.user)
                sourceforge_web_synchro( SOURCEFORGE_PROJECT, doc_distcheck_top_dir, user=options.user, sftp=options.sftp )
                print('Completed documentation upload')
            print('Uploading source and documentation tarballs for release using user', options.user)
            sourceforge_release_tarball( SOURCEFORGE_PROJECT,
                                         [source_tarball_path, doc_tarball_path],
                                         user=options.user, sftp=options.sftp )
            print('Source and doc release tarballs uploaded')
        else:
            print('No upload user specified. Web site and download tarbal were not uploaded.')
            print('Tarball can be found at:', doc_tarball_path)

        # Set next version number and commit            
        set_version( next_version )
        svn_commit( 'Released ' + release_version )
    else:
        sys.stderr.write( msg + '\n' )
 
if __name__ == '__main__':
    main()
