#!/usr/bin/env python

from __future__ import print_function
import argparse
import os
import sys

from catkin_pkg.packages import find_packages, verify_equal_package_versions

# find the import relatively if available to work before installing catkin or overlaying installed version
if os.path.exists(os.path.join(os.path.dirname(__file__), 'CMakeLists.txt')):
    sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'python'))
from catkin.package_version import bump_version
from catkin.workspace_vcs import get_repository_type, vcs_remotes


def get_commands(path, packages, vcs_type, bump, new_version, svn_url=None):
    result = []

    # bump version number
    script = os.path.relpath(os.path.join(os.path.dirname(__file__), 'catkin_package_version'))
    cmd = '%s --bump %s %s' % (script, bump, path)
    result.append(cmd)

    # commit modified package.xml
    package_xmls = [os.path.join(p, 'package.xml') for p in packages.keys()]
    cmd = '%s commit -m "%s" %s' % (vcs_type, new_version, ' '.join(package_xmls))
    result.append(cmd)
    # push changes
    if vcs_type in ['bzr', 'git', 'hg']:
        cmd = '%s push' % vcs_type
        result.append(cmd)

    # tag version
    if vcs_type in ['bzr', 'git', 'hg']:
        cmd = '%s tag %s' % (vcs_type, new_version)
        result.append(cmd)
        cmd = '%s push' % vcs_type
        if vcs_type == 'git':
            cmd += ' --tags'
        result.append(cmd)
    elif vcs_type == 'svn':
        TRUNK = '/trunk'
        BRANCHES = '/branches'
        TAGS = '/tags'
        if svn_url.endswith(TRUNK):
            base_url = svn_url[:-len(TRUNK)]
        elif os.path.dirname(svn_url).endswith(BRANCHES):
            base_url = os.path.dirname(svn_url)[:-len(BRANCHES)]
        elif os.path.dirname(svn_url).endswith(TAGS):
            base_url = os.path.dirname(svn_url)[:-len(TAGS)]
        else:
            raise RuntimeError('Could not determine base URL of SVN repository "%s"' % svn_url)
        tag_url = '%s/tags/%s' % (base_url, new_version)
        cmd = 'svn cp -m "tagging %s" %s %s' % (new_version, svn_url, tag_url)
        result.append(cmd)
    return result


def main():
    parser = argparse.ArgumentParser(
        description='Outputs the commands to bump the version number, commit the modified package.xml files and create a tag in the repository.')
    parser.add_argument('--bump', choices=('major', 'minor', 'patch'), default='patch', help='Which part of the version number to bump? (default: %(default)s)')
    args = parser.parse_args()

    path = '.'
    packages = find_packages(path)
    if not packages:
        print('No packages found', file=sys.stderr)
        sys.exit(1)
    old_version = verify_equal_package_versions(packages.values())
    new_version = bump_version(old_version, args.bump)

    vcs_type = get_repository_type(path)
    url = None
    if vcs_type is None:
        raise RuntimeError('Could not determine repository type of "%s"' % path)
    elif vcs_type == 'svn':
        url = vcs_remotes(path, 'svn')[5:]

    commands = get_commands(path=path,
                            packages=packages,
                            vcs_type=vcs_type,
                            bump=args.bump,
                            new_version=new_version,
                            svn_url=url)
    #print('Execute the following commands:\n')
    print(' && '.join(commands))


if __name__ == '__main__':
    rc = 0
    try:
        main()
    except Exception as e:
        print(e, file=sys.stderr)
        rc = 1
    sys.exit(rc)
