from launchpadlib.launchpad import Launchpad
from collections import defaultdict
import httplib2
from meta_release import MetaRelease, SourceMetaRelease, MetaReleaseJsons

class UbuntuDistroLaunchpad:
    """
    Use launchpadlib api to query for the package history tree
    of a target source_package_name + distro_series
    """
    def __init__(self, source_package_name=None, distro_series=None,
            distro_version=None, debug=False):

        self.source_package_name = source_package_name
        self.distro_series = distro_series
        self.distro_version = distro_version
        self.debug = debug

        self.launchpad = self.login()
        self.ubuntu = self.set_ubuntu()
        self.distro = self.set_distro()

        self.set_debug()

    def login(self):
        return Launchpad.login_anonymously('package_version_history_lookup', 'production')

    def set_debug(self):
        if self.debug is False:
            httplib2.debuglevel = 0
        else:
            if self.debug is True:
                print('HTTP Debugging Enabled')
                httplib.debuglevel = 1

    def set_ubuntu(self):
        return self.launchpad.distributions['ubuntu']

    def set_distro_series(self):
        return self.ubuntu.getSeries(name_or_version=self.distro_series)

    def set_version(self):
        return self.ubuntu.getSeries(name_or_version=self.distro_version)

    def set_distro(self):
        if self.distro_series and self.distro_version is None:
            return self.set_distro_series()
        elif self.distro_version and self.distro_series is None:
            return self.set_version()

class UbuntuPackageArchive:
    """
    NOTE: Separating the package archive and lookup process from setting the distro
    i think is better for organization
    """

    def __init__(self, archive='main'):
        self.archive = archive 
        self.ubuntu = self.set_ubuntu() 
        self.current_archive = self.set_archive()

    def set_ubuntu(self):
        return UbuntuDistroLaunchpad().ubuntu

    def set_main_archive(self):
        return self.ubuntu.main_archive
    
    def set_archive(self):
        if self.archive == 'main':
            return self.set_main_archive()
        else:
            return None

class UbuntuPackageHistory:
    def __init__(self, archive='main', source_package_name=None,
            distro_version=None, distro_series=None):
        self.archive = archive
        self.current_archive = UbuntuPackageArchive(archive).current_archive
        self.source_package_name = source_package_name
        self.distro_version = distro_version 
        self.distro_series = distro_series 
        self.distro = self.set_distro()

    def set_distro(self):
        if self.distro_series and self.distro_version is None:
            return UbuntuDistroLaunchpad(distro_series=self.distro_series).distro
        elif self.distro_version and self.distro_series is None:
            return UbuntuDistroLaunchpad(distro_version=self.distro_version).distro


    def get_published_sources(self):
        """ 
        this function needs self.source_package_name to be set
        TODO: investigate to see if this api call works with a version or if there is a version instead of distro_series param with getPublishedSources so we can use the self.distro instead of what we are setting for series = now
        """ 
        if self.source_package_name is None:
            print('Please instantiate a source_package_name if you wish to use this method')
        else:
            # this code here can/should be archive aware so we can get from the
            # others. see the comment in the set_main_archive() function.
            #archive = self.set_main_archive()
            #series = self.set_distro_series()
            distro = self.distro
            published_sources = self.current_archive.getPublishedSources(source_name = self.source_package_name, distro_series=distro)
            return published_sources

    def source_package_version_history(self):
        sources = self.get_published_sources()
        results = []
        for source in sources:
            source_package_name = source.source_package_name
            source_package_version = source.source_package_version
            results.append((source_package_name, source_package_version))

        d = defaultdict(list)
        for k, v in results:
            d[k].append(v)

        return sorted(d.items())

if __name__ == '__main__':
    meta_release = SourceMetaRelease().meta_release_parse()
    meta_release_jsons = MetaReleaseJsons(meta_release).build()

    upa = UbuntuPackageArchive()
    udl = UbuntuDistroLaunchpad()
    uph = UbuntuPackageHistory()


