import logging
import os
import re
import sys
from ubuntutools.archive import Dsc

orig_re = re.compile(r'.*\.orig\.tar\.[^.]+$')
component_re = re.compile(r'^(?P<pkgname>.*)_(?P<version>.*)\.orig-(?P<component>[^.]+)\.tar\.[^.]+$')

def component_tarball_matches(tarball, pkgname, version):
    m = component_re.match(tarball)
    if m:
        if m.group('pkgname') != pkgname or m.group('version') != version:
            return None
    return m

class GitUbuntuDscError(Exception):
    pass

class GitUbuntuDsc(Dsc):
    def __init__(self, dsc_path):
        self._dsc_path = dsc_path
        self._dsc_dir = os.path.dirname(os.path.abspath(dsc_path))
        self._orig = None
        self._components = None
        with open(self._dsc_path, 'rb') as dscf:
            super(GitUbuntuDsc, self).__init__(dscf)

    # adapted from ubuntutools.archive.SourcePackage.verify
    def verify(self):
        return all(self.verify_file(os.path.join(self.dsc_dir,
                                                 entry['name']))
                   for entry in self['Files'])

    @property
    def dsc_path(self):
        return self._dsc_path

    @property
    def dsc_dir(self):
        return self._dsc_dir

    @property
    def orig_tarball_path(self):
        if self._orig:
            return self._orig
        orig = None
        for entry in self['Files']:
            if orig_re.match(entry['name']):
                if orig is not None:
                    raise GitUbuntuDscError('Multiple base '
                        'orig tarballs in DSC')
                orig = os.path.join(self.dsc_dir, entry['name'])
                logging.debug('Verifying orig tarball %s', orig)
                if not self.verify_file(orig):
                    raise GitUbuntuDscError('Unable to verify orig '
                        'tarball %s' % orig)
        self._orig = orig
        return self._orig

    @property
    def component_tarball_paths(self):
        if self._components is not None:
            return self._components
        components = {}
        for entry in self['Files']:
            m = component_re.match(entry['name'])
            if m is not None:
                component_name = m.group('component')
                component = os.path.join(self.dsc_dir, entry['name'])
                logging.debug('Verifying component tarball %s', component)
                if not self.verify_file(component):
                    raise GitUbuntuDscError('Unable to verify component '
                        'tarball %s' % component)
                components[component_name] = component
        self._components = components
        return self._components

    @property
    def all_tarball_paths(self):
        return [self.orig_tarball_path] + list(self.component_tarball_paths.values())
