import os
import subprocess
from time import strftime

from ros_buildfarm.common import get_debian_package_name
from ros_buildfarm.release_common import dpkg_parsechangelog


def get_sourcedeb(
        rosdistro_name, package_name, sourcedeb_dir,
        skip_download_sourcedeb=False):
    # ensure that no source subfolder exists
    debian_package_name = get_debian_package_name(rosdistro_name, package_name)
    subfolders = _get_package_subfolders(sourcedeb_dir, debian_package_name)
    assert not subfolders, \
        ("Sourcedeb directory '%s' must not have any " +
         "subfolders starting with '%s-'") % (sourcedeb_dir, package_name)

    debian_package_name = get_debian_package_name(rosdistro_name, package_name)
    if not skip_download_sourcedeb:
        # download sourcedeb
        cmd = ['apt-get', 'source', debian_package_name, '--download-only']
        print("Invoking '%s'" % ' '.join(cmd))
        subprocess.check_call(cmd, cwd=sourcedeb_dir)

    # extract sourcedeb
    filenames = _get_package_dsc_filename(sourcedeb_dir, debian_package_name)
    assert len(filenames) == 1, filenames
    dsc_filename = filenames[0]
    cmd = ['dpkg-source', '-x', dsc_filename]
    print("Invoking '%s'" % ' '.join(cmd))
    subprocess.check_call(cmd, cwd=sourcedeb_dir)

    # ensure that one source subfolder exists
    subfolders = _get_package_subfolders(sourcedeb_dir, debian_package_name)
    assert len(subfolders) == 1, subfolders
    source_dir = subfolders[0]

    # output package maintainers for job notification
    from catkin_pkg.package import parse_package
    pkg = parse_package(source_dir)
    maintainer_emails = set([])
    for m in pkg.maintainers:
        maintainer_emails.add(m.email)
    if maintainer_emails:
        print('Package maintainer emails: %s' %
              ' '.join(sorted(maintainer_emails)))


def append_build_timestamp(rosdistro_name, package_name, sourcedeb_dir):
    # ensure that one source subfolder exists
    debian_package_name = get_debian_package_name(rosdistro_name, package_name)
    subfolders = _get_package_subfolders(sourcedeb_dir, debian_package_name)
    assert len(subfolders) == 1, subfolders
    source_dir = subfolders[0]

    source, version, distribution, urgency = dpkg_parsechangelog(
        source_dir, ['Source', 'Version', 'Distribution', 'Urgency'])
    cmd = [
        'debchange',
        '-v', '%s-%s' % (version, strftime('%Y%m%d-%H%M%S%z')),
        '-p',  # preserve directory name
        '-D', distribution,
        '-u', urgency,
        '-m',  # keep maintainer details
        'Append timestamp when binarydeb was built.',
    ]
    print("Invoking '%s' in '%s'" % (' '.join(cmd), source_dir))
    subprocess.check_call(cmd, cwd=source_dir)


def build_binarydeb(rosdistro_name, package_name, sourcedeb_dir):
    # ensure that one source subfolder exists
    debian_package_name = get_debian_package_name(rosdistro_name, package_name)
    subfolders = _get_package_subfolders(sourcedeb_dir, debian_package_name)
    assert len(subfolders) == 1, subfolders
    source_dir = subfolders[0]

    source, version = dpkg_parsechangelog(
        source_dir, ['Source', 'Version'])
    # output package version for job description
    print("Package '%s' version: %s" % (debian_package_name, version))

    cmd = ['apt-src', 'import', source, '--here', '--version', version]
    subprocess.check_call(cmd, cwd=source_dir)

    cmd = ['apt-src', 'build', source]
    print("Invoking '%s' in '%s'" % (' '.join(cmd), source_dir))
    subprocess.check_call(cmd, cwd=source_dir)


def _get_package_subfolders(basepath, debian_package_name):
    subfolders = []
    for filename in os.listdir(basepath):
        path = os.path.join(basepath, filename)
        if not os.path.isdir(path):
            continue
        if filename.startswith('%s-' % debian_package_name):
            subfolders.append(path)
    return subfolders


def _get_package_dsc_filename(basepath, debian_package_name):
    filenames = []
    for filename in os.listdir(basepath):
        if filename.startswith('%s_' % debian_package_name) and \
                filename.endswith('.dsc'):
            filenames.append(filename)
    return filenames

@@ -21,16 +21,27 @@
 process%0A
+import sys%0A
 from tim
@@ -57,16 +57,33 @@
 strftime
+%0Aimport traceback
 %0A%0Afrom r
@@ -3537,32 +3537,45 @@
 ), source_dir))%0A
+    try:%0A    
     subprocess.c
@@ -3601,24 +3601,608 @@
 source_dir)%0A
+    except subprocess.CalledProcessError:%0A        traceback.print_exc()%0A        sys.exit(%22%22%22%0A--------------------------------------------------------------------------------------------------%0A%60%7B0%7D%60 failed.%0AThis is usually because of an error building the package.%0AThe traceback from this failure (just above) is printed for completeness, but you can ignore it.%0AYou should look above %60E: Building failed%60 in the build log for the actual cause of the failure.%0A--------------------------------------------------------------------------------------------------%0A%22%22%22.format(' '.join(cmd)))%0A
 %0A%0Adef _get_p

improve the error message printed when a package build fails