#!/usr/bin/python
#
# Copyright (C) 2011 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import re
import os
import sys
import getopt
import shutil
import subprocess
import zipfile

VERBOSE = False
TOP_FOLDER = "src"
_RE_PKG = re.compile("^\s*package\s+([^\s;]+)\s*;.*")

# Holds cmd-line arguments and context information
class Params(object):
    def __init__(self):
        self.EXEC_ZIP = False
        self.DRY = False
        self.PROPS = None
        self.SRC = None
        self.DST = None
        self.CNT_USED = 0
        self.CNT_NOPKG = 0
        # DIR is the list of directories to scan in TOPDIR.
        self.DIR = "frameworks libcore"
        self.IGNORE_DIR = [ "hosttests", "tools", "tests", "samples" ]
        # IGNORE is a list of namespaces to ignore. Must be java
        # package definitions (e.g. "com.blah.foo.")
        self.IGNORE = [ "sun.", "libcore.", "dalvik.",
                        "com.test.", "com.google.",
                        "coretestutils.", "test.", "test2.", "tests." ]
        self.zipfile = None


def verbose(msg, *args):
    """Prints a verbose message to stderr if --verbose is set."""
    global VERBOSE
    if VERBOSE:
        if args:
            msg = msg % args
        print >>sys.stderr, msg


# Prints a usage summary
def usage(error=None):
    print """
 Description:
   This script collects all framework Java sources from the current android
   source code and places them in a source.zip file that can be distributed
   by the SDK Manager.

 Usage:
   %s [-n|-v|-z] <source.properties> <sources.zip> <topdir>

 The source.properties file must exist and will be injected in the Zip file.
 The source directory must already exist.
 Use -v for verbose output (lists each file being picked up or ignored).
 Use -n for a dry-run (doesn't write the zip file).
 Use -z to use the system 'zip' command instead of the Python Zip module.

""" % sys.argv[0]

    if error:
        print >>sys.stderr, "Error:", error


# Parse command line args, returns a Params instance or sys.exit(2) on error
# after printing the error and the usage.
def parseArgs(argv):
    global VERBOSE
    p = Params()
    error = None

    try:
        opts, args = getopt.getopt(argv[1:],
                         "zvns:",
                         [ "exec-zip", "verbose", "dry", "sourcedir=" ])
    except getopt.GetoptError, e:
        error = str(e)

    if error is None:
        for o, a in opts:
            if o in [ "-n", "--dry" ]:
                # Dry mode: don't copy/zip, print what would be done.
                p.DRY = True
            if o in [ "-v", "--verbose" ]:
                # Verbose mode. Display everything that's going on.
                VERBOSE = True
            elif o in [ "-s", "--sourcedir" ]:
                # The source directories to process (space separated list)
                p.DIR = a
            elif o in [ "-z", "--exec-zip" ]:
                # Don't use Python zip, instead call the 'zip' system exec.
                p.EXEC_ZIP = True

        if len(args) != 3:
            error = "Missing arguments: <source> <dest>"
        else:
            p.PROPS = args[0]
            p.DST = args[1]
            p.SRC = args[2]

            if not os.path.isfile(p.PROPS):
                error = "%s is not a file" % p.PROPS
            if not os.path.isdir(p.SRC):
                error = "%s is not a directory" % p.SRC

    if error:
        usage(error)
        sys.exit(2)

    return p


# Recursively parses the given directory and processes java files found
def parseSrcDir(p, srcdir):
    if not os.path.exists(srcdir):
        verbose("Error: Skipping unknown directory %s", srcdir)
        return

    for filename in os.listdir(srcdir):
        filepath = os.path.join(srcdir, filename)
        if filename.endswith(".java") and os.path.isfile(filepath):
            pkg = checkJavaFile(filepath)
            if not pkg:
                verbose("No package found in %s", filepath)
            if pkg:
                # Should we ignore this package?
                pkg2 = pkg
                if not "." in pkg2:
                    pkg2 += "."
                for ignore in p.IGNORE:
                    if pkg2.startswith(ignore):
                        verbose("Ignore package %s [%s]", pkg, filepath)
                        pkg = None
                        break

            if pkg:
                pkg = pkg.replace(".", os.path.sep)  # e.g. android.view => android/view
                copy(p, filepath, pkg)
                p.CNT_USED += 1
            else:
                p.CNT_NOPKG += 1
        elif os.path.isdir(filepath):
            if not filename in p.IGNORE_DIR:
                parseSrcDir(p, filepath)


# Check a java file to find its package declaration, if any
def checkJavaFile(path):
    try:
        f = None
        try:
            f = file(path)
            for l in f.readlines():
                m = _RE_PKG.match(l)
                if m:
                    return m.group(1)
        finally:
            if f: f.close()
    except Exception:
        pass

    return None


USED_ARC_PATH = {}

# Copy the given file (given its absolute filepath) to
# the relative desk_pkg directory in the zip file.
def copy(p, filepath, dest_pkg):
    arc_path = os.path.join(TOP_FOLDER, dest_pkg, os.path.basename(filepath))
    if arc_path in USED_ARC_PATH:
        verbose("Ignore duplicate archive path %s", arc_path)
    USED_ARC_PATH[arc_path] = 1
    if p.DRY:
        print >>sys.stderr, "zip %s [%s]" % (arc_path, filepath)
    elif p.zipfile is not None:
        if p.EXEC_ZIP:
            # zipfile is a path. Copy to it.
            dest_path = os.path.join(p.zipfile, arc_path)
            dest_dir = os.path.dirname(dest_path)
            if not os.path.isdir(dest_dir):
                os.makedirs(dest_dir)
            shutil.copyfile(filepath, dest_path)
        else:
            # zipfile is a ZipFile object. Compress with it.
            p.zipfile.write(filepath, arc_path)


def shellExec(*cmd):
  """
  Executes the given system command.

  The command must be split into a list (c.f. shext.split().)

  This raises an exception if the command fails.
  Stdin/out/err are not being redirected.
  """
  verbose("exec: %s", repr(cmd))
  subprocess.check_call(cmd)


def main():
    p = parseArgs(sys.argv)
    z = None
    try:
        if not p.DRY:
            if p.EXEC_ZIP:
                p.zipfile = p.DST + "_temp_dir"
                if os.path.exists(p.zipfile):
                    shutil.rmtree(p.zipfile)
                props_dest = os.path.join(p.zipfile, TOP_FOLDER + "/source.properties")
                os.makedirs(os.path.dirname(props_dest))
                shutil.copyfile(p.PROPS, props_dest)
            else:
                p.zipfile = z = zipfile.ZipFile(p.DST, "w", zipfile.ZIP_DEFLATED)
                z.write(p.PROPS, TOP_FOLDER + "/source.properties")
        for d in p.DIR.split():
            if d:
                parseSrcDir(p, os.path.join(p.SRC, d))
        if p.EXEC_ZIP and not p.DRY:
            curr_dir = os.getcwd()
            os.chdir(p.zipfile)
            if os.path.exists("_temp.zip"):
                os.unlink("_temp.zip");
            shellExec("zip", "-9r", "_temp.zip", TOP_FOLDER)
            os.chdir(curr_dir)
            shutil.move(os.path.join(p.zipfile, "_temp.zip"), p.DST)
            shutil.rmtree(p.zipfile)
    finally:
        if z is not None:
            z.close()
    print "%s: %d java files copied" % (p.DST, p.CNT_USED)
    if p.CNT_NOPKG:
        print "%s: %d java files ignored" % (p.DST, p.CNT_NOPKG)
    if p.DRY:
        print >>sys.stderr, "This was in *DRY* mode. No copies done."


if __name__ == "__main__":
    main()

# For emacs:
# -*- tab-width: 4; -*-
