import sys
import os

try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

from bento._config \
    import \
        IPKG_PATH
from bento.installed_package_description import \
        iter_source_files
from bento.conv import \
        to_distutils_meta

from bento.core import \
        PackageMetadata

def egg_filename(fullname, pyver=None):
    if not pyver:
        pyver = ".".join([str(i) for i in sys.version_info[:2]])
    return "%s-py%s.egg" % (fullname, pyver)

def egg_info_dirname(fullname, pyver=None):
    if not pyver:
        pyver = ".".join([str(i) for i in sys.version_info[:2]])
    return "%s-py%s.egg-info" % (fullname, pyver)

class EggInfo(object):
    @classmethod
    def from_ipkg(cls, ipkg):
        meta = PackageMetadata.from_ipkg(ipkg)
        executables = ipkg.executables

        file_sections = ipkg.resolve_paths()
        sources = list(iter_source_files(file_sections))

        ret = cls(meta, executables, sources)
        ret.ipkg = ipkg
        return ret

    def __init__(self, meta, executables, sources):
        self._dist_meta = to_distutils_meta(meta)

        self.sources = sources
        self.meta = meta
        self.executables = executables
        self.ipkg = None

    def get_pkg_info(self):
        tmp = StringIO()
        self._dist_meta.write_pkg_file(tmp)
        ret = tmp.getvalue()
        tmp.close()
        return ret

    def get_sources(self):
        return "\n".join([os.path.normpath(f) for f in self.sources])

    def get_install_requires(self):
        return "\n".join(self.meta.install_requires)

    def get_top_levels(self):
        # Last newline added for compatibility with setuptools
        return "\n".join(self.meta.top_levels + [''])

    def get_not_zip_safe(self):
        return "\n"

    def get_dependency_links(self):
        return "\n"

    def get_entry_points(self):
        ret = []
        ret.append("[console_scripts]")
        ret.extend([exe.full_representation() for exe in \
                        self.executables.values()])
        ret.append('')
        return "\n".join(ret)

    def get_ipkg_info(self):
        # FIXME: this is wrong. Rethink the EggInfo interface and its
        # relationship with ipkg
        if self.ipkg is None:
            f = open(IPKG_PATH)
            try:
                return f.read()
            finally:
                f.close()
        else:
            tmp = StringIO()
            self.ipkg._write(tmp)
            ret = tmp.getvalue()
            tmp.close()
            return ret

    def iter_meta(self):
        func_table = {
                "pkg_info": self.get_pkg_info,
                "sources": self.get_sources,
                "install_requires": self.get_install_requires,
                "top_levels": self.get_top_levels,
                "not_zip_safe": self.get_not_zip_safe,
                "dependency_links": self.get_dependency_links,
                "entry_points": self.get_entry_points,
                "ipkg_info": self.get_ipkg_info,
            }
        file_table = {
                "pkg_info": "PKG-INFO",
                "sources": "SOURCES.txt",
                "install_requires": "requires.txt",
                "top_levels": "top_level.txt",
                "not_zip_safe": "not-zip-safe",
                "dependency_links": "dependency_links.txt",
                "entry_points": "entry_points.txt",
                "ipkg_info": "ipkg.info",
            }

        for k in func_table:
            yield file_table[k], func_table[k]()

@@ -13,16 +13,31 @@
 mport os
+%0Aimport zipfile
 %0A%0Atry:%0A 
@@ -252,16 +252,41 @@
 ce_files
+, InstalledPkgDescription
 %0Afrom be
@@ -3604,8 +3604,851 @@
 le%5Bk%5D()%0A
+%0Adef extract_egg(egg, extract_dir):%0A    # Given a bento-produced egg, extract its content in the given directory,%0A    # and returned the corresponding ipkg info instance%0A    ipkg = InstalledPkgDescription.from_egg(egg)%0A    # egg scheme%0A    ipkg.update_paths(%7B%22prefix%22: %22.%22, %22eprefix%22: %22.%22, %22sitedir%22: %22.%22%7D)%0A%0A    zid = zipfile.ZipFile(egg)%0A    try:%0A        for type, sections in ipkg.files.items():%0A            for name, section in sections.items():%0A                target_dir = ipkg.resolve_path(section.target_dir)%0A                section.source_dir = os.path.join(extract_dir, target_dir)%0A                for source, target in section.files:%0A                    g = os.path.join(target_dir, target)%0A                    g = os.path.normpath(g)%0A                    zid.extract(g, extract_dir)%0A    finally:%0A        zid.close()%0A%0A    return ipkg%0A

add function to extract a bento-built egg.