/*
 * Copyright (C) 2014 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.
 */



package com.android.build.gradle.internal.tasks.multidex
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction

import java.util.jar.JarEntry
import java.util.jar.JarOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream

/**
 * Custom Jar task that can merge other jars.
 * This ignores all non .class files since this is strictly to
 * handle code.
 */
class JarMergingTask extends DefaultTask {

    // could be files (jar) or folders of classes.
    @InputFiles
    Collection<File> inputJars

    @InputDirectory @Optional
    File inputDir

    @OutputFile
    File jarFile

    @TaskAction
    void createJar() {
        jarFile.delete()

        FileOutputStream fos = new FileOutputStream(jarFile)
        JarOutputStream jos = new JarOutputStream(fos)

        final byte[] buffer = new byte[8192]

        for (File file : getInputJars()) {
            processJarFile(jos, file, buffer)
        }

        File _inputDir = getInputDir()
        if (_inputDir != null) {
            processFolder(jos, "", _inputDir, buffer)
        }

        jos.close()
    }

    private void processFolder(JarOutputStream jos, String path, File folder, byte[] buffer) {
        for (File file : folder.listFiles()) {
            if (file.isFile()) {
                // new entry
                jos.putNextEntry(new JarEntry(path + file.getName()))

                // put the file content
                FileInputStream fis = new FileInputStream(file)
                int count
                while ((count = fis.read(buffer)) != -1) {
                    jos.write(buffer, 0, count)
                }
                fis.close()

                // close the entry
                jos.closeEntry()
            } else if (file.isDirectory()) {
                processFolder(jos, path + file.getName() + "/", file, buffer)
            }
        }
    }

    private static void processJarFile(JarOutputStream jos, File file, byte[] buffer) {
        FileInputStream fis = new FileInputStream(file)
        ZipInputStream zis = new ZipInputStream(fis)

        try {
            // loop on the entries of the jar file package and put them in the final jar
            ZipEntry entry
            while ((entry = zis.getNextEntry()) != null) {
                // do not take directories or anything inside a potential META-INF folder.
                if (entry.isDirectory()) {
                    continue
                }

                String name = entry.getName()
                if (!name.endsWith(".class")) {
                    continue
                }

                JarEntry newEntry

                // Preserve the STORED method of the input entry.
                if (entry.getMethod() == JarEntry.STORED) {
                    newEntry = new JarEntry(entry)
                } else {
                    // Create a new entry so that the compressed len is recomputed.
                    newEntry = new JarEntry(name)
                }

                // add the entry to the jar archive
                jos.putNextEntry(newEntry)

                // read the content of the entry from the input stream, and write it into the archive.
                int count
                while ((count = zis.read(buffer)) != -1) {
                    jos.write(buffer, 0, count)
                }

                // close the entries for this file
                jos.closeEntry()
                zis.closeEntry()
            }
        } finally {
            zis.close()
        }

        fis.close()
    }
}
