# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from __future__ import absolute_import

import mozpack.path as mozpath
from mozpack.files import (
    FileFinder,
    DeflatedFile,
    ManifestFile,
)
from mozpack.chrome.manifest import (
    parse_manifest,
    ManifestEntryWithRelPath,
    ManifestResource,
    is_manifest,
)
from mozpack.mozjar import JarReader
from mozpack.copier import (
    FileRegistry,
    FileCopier,
)
from mozpack.packager import SimplePackager
from mozpack.packager.formats import (
    FlatFormatter,
    STARTUP_CACHE_PATHS,
)
from urlparse import urlparse


class UnpackFinder(FileFinder):
    '''
    Special FileFinder that treats the source package directory as if it were
    in the flat chrome format, whatever chrome format it actually is in.

    This means that for example, paths like chrome/browser/content/... match
    files under jar:chrome/browser.jar!/content/... in case of jar chrome
    format.
    '''
    def __init__(self, *args, **kargs):
        FileFinder.__init__(self, *args, **kargs)
        self.files = FileRegistry()
        self.kind = 'flat'
        self.omnijar = None
        self.jarlogs = {}
        self.optimizedjars = False

        jars = set()

        for p, f in FileFinder.find(self, '*'):
            # Skip the precomplete file, which is generated at packaging time.
            if p == 'precomplete':
                continue
            base = mozpath.dirname(p)
            # If the file is a zip/jar that is not a .xpi, and contains a
            # chrome.manifest, it is an omnijar. All the files it contains
            # go in the directory containing the omnijar. Manifests are merged
            # if there is a corresponding manifest in the directory.
            if not p.endswith('.xpi') and self._maybe_zip(f) and \
                    (mozpath.basename(p) == self.omnijar or
                     not self.omnijar):
                jar = self._open_jar(p, f)
                if 'chrome.manifest' in jar:
                    self.kind = 'omni'
                    self.omnijar = mozpath.basename(p)
                    self._fill_with_jar(base, jar)
                    continue
            # If the file is a manifest, scan its entries for some referencing
            # jar: urls. If there are some, the files contained in the jar they
            # point to, go under a directory named after the jar.
            if is_manifest(p):
                m = self.files[p] if self.files.contains(p) \
                    else ManifestFile(base)
                for e in parse_manifest(self.base, p, f.open()):
                    m.add(self._handle_manifest_entry(e, jars))
                if self.files.contains(p):
                    continue
                f = m
            # If the file is a packed addon, unpack it under a directory named
            # after the xpi.
            if p.endswith('.xpi') and self._maybe_zip(f):
                self._fill_with_jar(p[:-4], self._open_jar(p, f))
                continue
            if not p in jars:
                self.files.add(p, f)

    def _fill_with_jar(self, base, jar):
        for j in jar:
            path = mozpath.join(base, j.filename)
            if is_manifest(j.filename):
                m = self.files[path] if self.files.contains(path) \
                    else ManifestFile(mozpath.dirname(path))
                for e in parse_manifest(None, path, j):
                    m.add(e)
                if not self.files.contains(path):
                    self.files.add(path, m)
                continue
            else:
                self.files.add(path, DeflatedFile(j))

    def _handle_manifest_entry(self, entry, jars):
        jarpath = None
        if isinstance(entry, ManifestEntryWithRelPath) and \
                urlparse(entry.relpath).scheme == 'jar':
            jarpath, entry = self._unjarize(entry, entry.relpath)
        elif isinstance(entry, ManifestResource) and \
                urlparse(entry.target).scheme == 'jar':
            jarpath, entry = self._unjarize(entry, entry.target)
        if jarpath:
            # Don't defer unpacking the jar file. If we already saw
            # it, take (and remove) it from the registry. If we
            # haven't, try to find it now.
            if self.files.contains(jarpath):
                jar = self.files[jarpath]
                self.files.remove(jarpath)
            else:
                jar = [f for p, f in FileFinder.find(self, jarpath)]
                assert len(jar) == 1
                jar = jar[0]
            if not jarpath in jars:
                base = mozpath.splitext(jarpath)[0]
                for j in self._open_jar(jarpath, jar):
                    self.files.add(mozpath.join(base,
                                                     j.filename),
                                   DeflatedFile(j))
            jars.add(jarpath)
            self.kind = 'jar'
        return entry

    def _open_jar(self, path, file):
        '''
        Return a JarReader for the given BaseFile instance, keeping a log of
        the preloaded entries it has.
        '''
        jar = JarReader(fileobj=file.open())
        if jar.is_optimized:
            self.optimizedjars = True
        if jar.last_preloaded:
            jarlog = jar.entries.keys()
            self.jarlogs[path] = jarlog[:jarlog.index(jar.last_preloaded) + 1]
        return jar

    def find(self, path):
        for p in self.files.match(path):
            yield p, self.files[p]

    def _maybe_zip(self, file):
        '''
        Return whether the given BaseFile looks like a ZIP/Jar.
        '''
        header = file.open().read(8)
        return len(header) == 8 and (header[0:2] == 'PK' or
                                     header[4:6] == 'PK')

    def _unjarize(self, entry, relpath):
        '''
        Transform a manifest entry pointing to chrome data in a jar in one
        pointing to the corresponding unpacked path. Return the jar path and
        the new entry.
        '''
        base = entry.base
        jar, relpath = urlparse(relpath).path.split('!', 1)
        entry = entry.rebase(mozpath.join(base, 'jar:%s!' % jar)) \
            .move(mozpath.join(base, mozpath.splitext(jar)[0])) \
            .rebase(base)
        return mozpath.join(base, jar), entry


def unpack_to_registry(source, registry):
    '''
    Transform a jar chrome or omnijar packaged directory into a flat package.

    The given registry is filled with the flat package.
    '''
    finder = UnpackFinder(source)
    packager = SimplePackager(FlatFormatter(registry))
    for p, f in finder.find('*'):
        if mozpath.split(p)[0] not in STARTUP_CACHE_PATHS:
            packager.add(p, f)
    packager.close()


def unpack(source):
    '''
    Transform a jar chrome or omnijar packaged directory into a flat package.
    '''
    copier = FileCopier()
    unpack_to_registry(source, copier)
    copier.copy(source, skip_if_older=False)
