# Copyright 2010 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

"""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()
