// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.regex.Pattern;
import java.util.zip.CRC32;

/**
 * Command line tool used to build APKs which support loading the native code library
 * directly from the APK file. To construct the APK we rename the native library by
 * adding the prefix "crazy." to the filename. This is done to prevent the Android
 * Package Manager from extracting the library. The native code must be page aligned
 * and uncompressed. The page alignment is implemented by adding a zero filled file
 * in front of the the native code library. This tool is designed so that running
 * SignApk and/or zipalign on the resulting APK does not break the page alignment.
 * This is achieved by outputing the filenames in the same canonical order used
 * by SignApk and adding the same alignment fields added by zipalign.
 */
class RezipApk {
    // Alignment to use for non-compressed files (must match zipalign).
    private static final int ALIGNMENT = 4;

    // Alignment to use for non-compressed *.so files
    private static final int LIBRARY_ALIGNMENT = 4096;

    // Files matching this pattern are not copied to the output when adding alignment.
    // When reordering and verifying the APK they are copied to the end of the file.
    private static Pattern sMetaFilePattern =
            Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA)|com/android/otacert))|("
                    + Pattern.quote(JarFile.MANIFEST_NAME) + ")$");

    // Pattern for matching a shared library in the APK
    private static Pattern sLibraryPattern = Pattern.compile("^lib/[^/]*/lib.*[.]so$");
    // Pattern for match the crazy linker in the APK
    private static Pattern sCrazyLinkerPattern =
            Pattern.compile("^lib/[^/]*/libchromium_android_linker.so$");
    // Pattern for matching a crazy loaded shared library in the APK
    private static Pattern sCrazyLibraryPattern = Pattern.compile("^lib/[^/]*/crazy.lib.*[.]so$");

    private static boolean isLibraryFilename(String filename) {
        return sLibraryPattern.matcher(filename).matches()
                && !sCrazyLinkerPattern.matcher(filename).matches();
    }

    private static boolean isCrazyLibraryFilename(String filename) {
        return sCrazyLibraryPattern.matcher(filename).matches();
    }

    private static String renameLibraryForCrazyLinker(String filename) {
        int lastSlash = filename.lastIndexOf('/');
        // We rename the library, so that the Android Package Manager
        // no longer extracts the library.
        return filename.substring(0, lastSlash + 1) + "crazy." + filename.substring(lastSlash + 1);
    }

    /**
     * Wraps another output stream, counting the number of bytes written.
     */
    private static class CountingOutputStream extends OutputStream {
        private long mCount = 0;
        private OutputStream mOut;

        public CountingOutputStream(OutputStream out) {
            this.mOut = out;
        }

        /** Returns the number of bytes written. */
        public long getCount() {
            return mCount;
        }

        @Override public void write(byte[] b, int off, int len) throws IOException {
            mOut.write(b, off, len);
            mCount += len;
        }

        @Override public void write(int b) throws IOException {
            mOut.write(b);
            mCount++;
        }

        @Override public void close() throws IOException {
            mOut.close();
        }

        @Override public void flush() throws IOException {
            mOut.flush();
        }
    }

    private static String outputName(JarEntry entry, boolean rename) {
        String inName = entry.getName();
        if (rename && entry.getSize() > 0 && isLibraryFilename(inName)) {
            return renameLibraryForCrazyLinker(inName);
        }
        return inName;
    }

    /**
     * Comparator used to sort jar entries from the input file.
     * Sorting is done based on the output filename (which maybe renamed).
     * Filenames are in natural string order, except that filenames matching
     * the meta-file pattern are always after other files. This is so the manifest
     * and signature are at the end of the file after any alignment file.
     */
    private static class EntryComparator implements Comparator<JarEntry> {
        private boolean mRename;

        public EntryComparator(boolean rename) {
            mRename = rename;
        }

        @Override
        public int compare(JarEntry j1, JarEntry j2) {
            String o1 = outputName(j1, mRename);
            String o2 = outputName(j2, mRename);
            boolean o1Matches = sMetaFilePattern.matcher(o1).matches();
            boolean o2Matches = sMetaFilePattern.matcher(o2).matches();
            if (o1Matches != o2Matches) {
                return o1Matches ? 1 : -1;
            } else {
                return o1.compareTo(o2);
            }
        }
    }

    // Build an ordered list of jar entries. The jar entries from the input are
    // sorted based on the output filenames (which maybe renamed). If |omitMetaFiles|
    // is true do not include the jar entries for the META-INF files.
    // Entries are ordered in the deterministic order used by SignApk.
    private static List<JarEntry> getOutputFileOrderEntries(
            JarFile jar, boolean omitMetaFiles, boolean rename) {
        List<JarEntry> entries = new ArrayList<JarEntry>();
        for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements(); ) {
            JarEntry entry = e.nextElement();
            if (entry.isDirectory()) {
                continue;
            }
            if (omitMetaFiles && sMetaFilePattern.matcher(entry.getName()).matches()) {
                continue;
            }
            entries.add(entry);
        }

        // We sort the input entries by name. When present META-INF files
        // are sorted to the end.
        Collections.sort(entries, new EntryComparator(rename));
        return entries;
    }

    /**
     * Add a zero filled alignment file at this point in the zip file,
     * The added file will be added before |name| and after |prevName|.
     * The size of the alignment file is such that the location of the
     * file |name| will be on a LIBRARY_ALIGNMENT boundary.
     *
     * Note this arrangement is devised so that running SignApk and/or zipalign on the resulting
     * file will not alter the alignment.
     *
     * @param offset number of bytes into the output file at this point.
     * @param timestamp time in millis since the epoch to include in the header.
     * @param name the name of the library filename.
     * @param prevName the name of the previous file in the archive (or null).
     * @param out jar output stream to write the alignment file to.
     *
     * @throws IOException if the output file can not be written.
     */
    private static void addAlignmentFile(
            long offset, long timestamp, String name, String prevName,
            JarOutputStream out) throws IOException {

        // Compute the start and alignment of the library, as if it was next.
        int headerSize = JarFile.LOCHDR + name.length();
        long libOffset = offset + headerSize;
        int libNeeded = LIBRARY_ALIGNMENT - (int) (libOffset % LIBRARY_ALIGNMENT);
        if (libNeeded == LIBRARY_ALIGNMENT) {
            // Already aligned, no need to added alignment file.
            return;
        }

        // Check that there is not another file between the library and the
        // alignment file.
        String alignName = name.substring(0, name.length() - 2) + "align";
        if (prevName != null && prevName.compareTo(alignName) >= 0) {
            throw new UnsupportedOperationException(
                "Unable to insert alignment file, because there is "
                + "another file in front of the file to be aligned. "
                + "Other file: " + prevName + " Alignment file: " + alignName
                + " file: " + name);
        }

        // Compute the size of the alignment file header.
        headerSize = JarFile.LOCHDR + alignName.length();
        // We are going to add an alignment file of type STORED. This file
        // will itself induce a zipalign alignment adjustment.
        int extraNeeded =
                (ALIGNMENT - (int) ((offset + headerSize) % ALIGNMENT)) % ALIGNMENT;
        headerSize += extraNeeded;

        if (libNeeded < headerSize + 1) {
            // The header was bigger than the alignment that we need, add another page.
            libNeeded += LIBRARY_ALIGNMENT;
        }
        // Compute the size of the alignment file.
        libNeeded -= headerSize;

        // Build the header for the alignment file.
        byte[] zeroBuffer = new byte[libNeeded];
        JarEntry alignEntry = new JarEntry(alignName);
        alignEntry.setMethod(JarEntry.STORED);
        alignEntry.setSize(libNeeded);
        alignEntry.setTime(timestamp);
        CRC32 crc = new CRC32();
        crc.update(zeroBuffer);
        alignEntry.setCrc(crc.getValue());

        if (extraNeeded != 0) {
            alignEntry.setExtra(new byte[extraNeeded]);
        }

        // Output the alignment file.
        out.putNextEntry(alignEntry);
        out.write(zeroBuffer);
        out.closeEntry();
        out.flush();
    }

    // Make a JarEntry for the output file which corresponds to the input
    // file. The output file will be called |name|. The output file will always
    // be uncompressed (STORED). If the input is not STORED it is necessary to inflate
    // it to compute the CRC and size of the output entry.
    private static JarEntry makeStoredEntry(String name, JarEntry inEntry, JarFile in)
            throws IOException {
        JarEntry outEntry = new JarEntry(name);
        outEntry.setMethod(JarEntry.STORED);

        if (inEntry.getMethod() == JarEntry.STORED) {
            outEntry.setCrc(inEntry.getCrc());
            outEntry.setSize(inEntry.getSize());
        } else {
            // We are inflating the file. We need to compute the CRC and size.
            byte[] buffer = new byte[4096];
            CRC32 crc = new CRC32();
            int size = 0;
            int num;
            InputStream data = in.getInputStream(inEntry);
            while ((num = data.read(buffer)) > 0) {
                crc.update(buffer, 0, num);
                size += num;
            }
            data.close();
            outEntry.setCrc(crc.getValue());
            outEntry.setSize(size);
        }
        return outEntry;
    }

    /**
     * Copy the contents of the input APK file to the output APK file. If |rename| is
     * true then non-empty libraries (*.so) in the input will be renamed by prefixing
     * "crazy.". This is done to prevent the Android Package Manager extracting the
     * library. Note the crazy linker itself is not renamed, for bootstrapping reasons.
     * Empty libraries are not renamed (they are in the APK to workaround a bug where
     * the Android Package Manager fails to delete old versions when upgrading).
     * There must be exactly one "crazy" library in the output stream. The "crazy"
     * library will be uncompressed and page aligned in the output stream. Page
     * alignment is implemented by adding a zero filled file, regular alignment is
     * implemented by adding a zero filled extra field to the zip file header. If
     * |addAlignment| is true a page alignment file is added, otherwise the "crazy"
     * library must already be page aligned. Care is taken so that the output is generated
     * in the same way as SignApk. This is important so that running SignApk and
     * zipalign on the output does not break the page alignment. The archive may not
     * contain a "*.apk" as SignApk has special nested signing logic that we do not
     * support.
     *
     * @param in The input APK File.
     * @param out The output APK stream.
     * @param countOut Counting output stream (to measure the current offset).
     * @param addAlignment Whether to add the alignment file or just check.
     * @param rename Whether to rename libraries to be "crazy".
     *
     * @throws IOException if the output file can not be written.
     */
    private static void rezip(
            JarFile in, JarOutputStream out, CountingOutputStream countOut,
            boolean addAlignment, boolean rename) throws IOException {

        List<JarEntry> entries = getOutputFileOrderEntries(in, addAlignment, rename);
        long timestamp = System.currentTimeMillis();
        byte[] buffer = new byte[4096];
        boolean firstEntry = true;
        String prevName = null;
        int numCrazy = 0;
        for (JarEntry inEntry : entries) {
            // Rename files, if specied.
            String name = outputName(inEntry, rename);
            if (name.endsWith(".apk")) {
                throw new UnsupportedOperationException(
                        "Nested APKs are not supported: " + name);
            }

            // Build the header.
            JarEntry outEntry = null;
            boolean isCrazy = isCrazyLibraryFilename(name);
            if (isCrazy) {
                // "crazy" libraries are alway output uncompressed (STORED).
                outEntry = makeStoredEntry(name, inEntry, in);
                numCrazy++;
                if (numCrazy > 1) {
                    throw new UnsupportedOperationException(
                            "Found more than one library\n"
                            + "Multiple libraries are not supported for APKs that use "
                            + "'load_library_from_zip_file'.\n"
                            + "See crbug/388223.\n"
                            + "Note, check that your build is clean.\n"
                            + "An unclean build can incorrectly incorporate old "
                            + "libraries in the APK.");
                }
            } else if (inEntry.getMethod() == JarEntry.STORED) {
                // Preserve the STORED method of the input entry.
                outEntry = new JarEntry(inEntry);
                outEntry.setExtra(null);
            } else {
                // Create a new entry so that the compressed len is recomputed.
                outEntry = new JarEntry(name);
            }
            outEntry.setTime(timestamp);

            // Compute and add alignment
            long offset = countOut.getCount();
            if (firstEntry) {
                // The first entry in a jar file has an extra field of
                // four bytes that you can't get rid of; any extra
                // data you specify in the JarEntry is appended to
                // these forced four bytes.  This is JAR_MAGIC in
                // JarOutputStream; the bytes are 0xfeca0000.
                firstEntry = false;
                offset += 4;
            }
            if (outEntry.getMethod() == JarEntry.STORED) {
                if (isCrazy) {
                    if (addAlignment) {
                        addAlignmentFile(offset, timestamp, name, prevName, out);
                    }
                    // We check that we did indeed get to a page boundary.
                    offset = countOut.getCount() + JarFile.LOCHDR + name.length();
                    if ((offset % LIBRARY_ALIGNMENT) != 0) {
                        throw new AssertionError(
                                "Library was not page aligned when verifying page alignment. "
                                + "Library name: " + name + " Expected alignment: "
                                + LIBRARY_ALIGNMENT + "Offset: " + offset + " Error: "
                                + (offset % LIBRARY_ALIGNMENT));
                    }
                } else {
                    // This is equivalent to zipalign.
                    offset += JarFile.LOCHDR + name.length();
                    int needed = (ALIGNMENT - (int) (offset % ALIGNMENT)) % ALIGNMENT;
                    if (needed != 0) {
                        outEntry.setExtra(new byte[needed]);
                    }
                }
            }
            out.putNextEntry(outEntry);

            // Copy the data from the input to the output
            int num;
            InputStream data = in.getInputStream(inEntry);
            while ((num = data.read(buffer)) > 0) {
                out.write(buffer, 0, num);
            }
            data.close();
            out.closeEntry();
            out.flush();
            prevName = name;
        }
        if (numCrazy == 0) {
            throw new AssertionError("There was no crazy library in the archive");
        }
    }

    private static void usage() {
        System.err.println("Usage: prealignapk (addalignment|reorder) input.apk output.apk");
        System.err.println("\"crazy\" libraries are always inflated in the output");
        System.err.println(
                "  renamealign  - rename libraries with \"crazy.\" prefix and add alignment file");
        System.err.println("  align        - add alignment file");
        System.err.println("  reorder      - re-creates canonical ordering and checks alignment");
        System.exit(2);
    }

    public static void main(String[] args) throws IOException {
        if (args.length != 3) usage();

        boolean addAlignment = false;
        boolean rename = false;
        if (args[0].equals("renamealign")) {
            // Normal case. Before signing we rename the library and add an alignment file.
            addAlignment = true;
            rename = true;
        } else if (args[0].equals("align")) {
            // LGPL compliance case. Before signing, we add an alignment file to a
            // reconstructed APK which already contains the "crazy" library.
            addAlignment = true;
            rename = false;
        } else if (args[0].equals("reorder")) {
            // Normal case. After jarsigning we write the file in the canonical order and check.
            addAlignment = false;
        } else {
            usage();
        }

        String inputFilename = args[1];
        String outputFilename = args[2];

        JarFile inputJar = null;
        FileOutputStream outputFile = null;

        try {
            inputJar = new JarFile(new File(inputFilename), true);
            outputFile = new FileOutputStream(outputFilename);

            CountingOutputStream outCount = new CountingOutputStream(outputFile);
            JarOutputStream outputJar = new JarOutputStream(outCount);

            // Match the compression level used by SignApk.
            outputJar.setLevel(9);

            rezip(inputJar, outputJar, outCount, addAlignment, rename);
            outputJar.close();
        } finally {
            if (inputJar != null) inputJar.close();
            if (outputFile != null) outputFile.close();
        }
    }
}
