/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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.ide.eclipse.adt.internal.build.builders;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AndroidPrintStream;
import com.android.ide.eclipse.adt.internal.build.AaptExecException;
import com.android.ide.eclipse.adt.internal.build.AaptParser;
import com.android.ide.eclipse.adt.internal.build.AaptResultException;
import com.android.ide.eclipse.adt.internal.build.BuildHelper;
import com.android.ide.eclipse.adt.internal.build.BuildHelper.ResourceMarker;
import com.android.ide.eclipse.adt.internal.build.DexException;
import com.android.ide.eclipse.adt.internal.build.Messages;
import com.android.ide.eclipse.adt.internal.build.NativeLibInJarException;
import com.android.ide.eclipse.adt.internal.lint.LintDeltaProcessor;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.project.ApkInstallManager;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.LibraryClasspathContainerInitializer;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.io.IFileWrapper;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.build.ApkBuilder;
import com.android.sdklib.build.ApkCreationException;
import com.android.sdklib.build.DuplicateFileException;
import com.android.sdklib.build.IArchiveBuilder;
import com.android.sdklib.build.SealedApkException;
import com.android.sdklib.internal.build.DebugKeyProvider.KeytoolException;
import com.android.xml.AndroidManifest;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.regex.Pattern;

public class PostCompilerBuilder extends BaseBuilder {

    /** This ID is used in plugin.xml and in each project's .project file.
     * It cannot be changed even if the class is renamed/moved */
    public static final String ID = "com.android.ide.eclipse.adt.ApkBuilder"; //$NON-NLS-1$

    private static final String PROPERTY_CONVERT_TO_DEX = "convertToDex"; //$NON-NLS-1$
    private static final String PROPERTY_PACKAGE_RESOURCES = "packageResources"; //$NON-NLS-1$
    private static final String PROPERTY_BUILD_APK = "buildApk"; //$NON-NLS-1$

    /** Flag to pass to PostCompiler builder that sets if it runs or not.
     *  Set this flag whenever calling build if PostCompiler is to run
     */
    public final static String POST_C_REQUESTED = "RunPostCompiler"; //$NON-NLS-1$

    /**
     * Dex conversion flag. This is set to true if one of the changed/added/removed
     * file is a .class file. Upon visiting all the delta resource, if this
     * flag is true, then we know we'll have to make the "classes.dex" file.
     */
    private boolean mConvertToDex = false;

    /**
     * Package resources flag. This is set to true if one of the changed/added/removed
     * file is a resource file. Upon visiting all the delta resource, if
     * this flag is true, then we know we'll have to repackage the resources.
     */
    private boolean mPackageResources = false;

    /**
     * Final package build flag.
     */
    private boolean mBuildFinalPackage = false;

    private AndroidPrintStream mOutStream = null;
    private AndroidPrintStream mErrStream = null;


    private ResourceMarker mResourceMarker = new ResourceMarker() {
        @Override
        public void setWarning(IResource resource, String message) {
            BaseProjectHelper.markResource(resource, AdtConstants.MARKER_PACKAGING,
                    message, IMarker.SEVERITY_WARNING);
        }
    };


    public PostCompilerBuilder() {
        super();
    }

    @Override
    protected void clean(IProgressMonitor monitor) throws CoreException {
        super.clean(monitor);

        // Get the project.
        IProject project = getProject();

        if (DEBUG_LOG) {
            AdtPlugin.log(IStatus.INFO, "%s CLEAN(POST)", project.getName());
        }

        // Clear the project of the generic markers
        removeMarkersFromContainer(project, AdtConstants.MARKER_AAPT_PACKAGE);
        removeMarkersFromContainer(project, AdtConstants.MARKER_PACKAGING);

        // also remove the files in the output folder (but not the Eclipse output folder).
        IFolder javaOutput = BaseProjectHelper.getJavaOutputFolder(project);
        IFolder androidOutput = BaseProjectHelper.getAndroidOutputFolder(project);

        if (javaOutput.equals(androidOutput) == false) {
            // get the content
            IResource[] members = androidOutput.members();
            for (IResource member : members) {
                if (member.equals(javaOutput) == false) {
                    member.delete(true /*force*/, monitor);
                }
            }
        }
    }

    // build() returns a list of project from which this project depends for future compilation.
    @Override
    protected IProject[] build(
            int kind,
            @SuppressWarnings("rawtypes") Map args,
            IProgressMonitor monitor)
            throws CoreException {
        // get a project object
        IProject project = getProject();

        if (DEBUG_LOG) {
            AdtPlugin.log(IStatus.INFO, "%s BUILD(POST)", project.getName());
        }

        // Benchmarking start
        long startBuildTime = 0;
        if (BuildHelper.BENCHMARK_FLAG) {
            // End JavaC Timer
            String msg = "BENCHMARK ADT: Ending Compilation \n BENCHMARK ADT: Time Elapsed: " +    //$NON-NLS-1$
                         (System.nanoTime() - BuildHelper.sStartJavaCTime)/Math.pow(10, 6) + "ms"; //$NON-NLS-1$
            AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg);
            msg = "BENCHMARK ADT: Starting PostCompilation";                                       //$NON-NLS-1$
            AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg);
            startBuildTime = System.nanoTime();
        }

        // list of referenced projects. This is a mix of java projects and library projects
        // and is computed below.
        IProject[] allRefProjects = null;

        try {
            // get the project info
            ProjectState projectState = Sdk.getProjectState(project);

            // this can happen if the project has no project.properties.
            if (projectState == null) {
                return null;
            }

            boolean isLibrary = projectState.isLibrary();

            // get the libraries
            List<IProject> libProjects = projectState.getFullLibraryProjects();

            IJavaProject javaProject = JavaCore.create(project);

            // get the list of referenced projects.
            List<IProject> javaProjects = ProjectHelper.getReferencedProjects(project);
            List<IJavaProject> referencedJavaProjects = BuildHelper.getJavaProjects(
                    javaProjects);

            // mix the java project and the library projects
            final int size = libProjects.size() + javaProjects.size();
            ArrayList<IProject> refList = new ArrayList<IProject>(size);
            refList.addAll(libProjects);
            refList.addAll(javaProjects);
            allRefProjects = refList.toArray(new IProject[size]);

            // get the android output folder
            IFolder androidOutputFolder = BaseProjectHelper.getAndroidOutputFolder(project);
            IFolder resOutputFolder = androidOutputFolder.getFolder(SdkConstants.FD_RES);

            // First thing we do is go through the resource delta to not
            // lose it if we have to abort the build for any reason.
            if (args.containsKey(POST_C_REQUESTED)
                    && AdtPrefs.getPrefs().getBuildSkipPostCompileOnFileSave()) {
                // Skip over flag setting
            } else if (kind == FULL_BUILD) {
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                        Messages.Start_Full_Apk_Build);

                if (DEBUG_LOG) {
                    AdtPlugin.log(IStatus.INFO, "%s full build!", project.getName());
                }

                // Full build: we do all the steps.
                mPackageResources = true;
                mConvertToDex = true;
                mBuildFinalPackage = true;
            } else {
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                        Messages.Start_Inc_Apk_Build);

                // go through the resources and see if something changed.
                IResourceDelta delta = getDelta(project);
                if (delta == null) {
                    // no delta? Same as full build: we do all the steps.
                    mPackageResources = true;
                    mConvertToDex = true;
                    mBuildFinalPackage = true;
                } else {

                    if (ResourceManager.isAutoBuilding() && AdtPrefs.getPrefs().isLintOnSave()) {
                        // Check for errors on save/build, if enabled
                        LintDeltaProcessor.create().process(delta);
                    }

                    PatternBasedDeltaVisitor dv = new PatternBasedDeltaVisitor(
                            project, project,
                            "POST:Main");

                    ChangedFileSet manifestCfs = ChangedFileSetHelper.getMergedManifestCfs(project);
                    dv.addSet(manifestCfs);

                    ChangedFileSet resCfs = ChangedFileSetHelper.getResCfs(project);
                    dv.addSet(resCfs);

                    ChangedFileSet androidCodeCfs = ChangedFileSetHelper.getCodeCfs(project);
                    dv.addSet(androidCodeCfs);

                    ChangedFileSet javaResCfs = ChangedFileSetHelper.getJavaResCfs(project);
                    dv.addSet(javaResCfs);
                    dv.addSet(ChangedFileSetHelper.NATIVE_LIBS);

                    delta.accept(dv);

                    // save the state
                    mPackageResources |= dv.checkSet(manifestCfs) || dv.checkSet(resCfs);

                    mConvertToDex |= dv.checkSet(androidCodeCfs);

                    mBuildFinalPackage |= dv.checkSet(javaResCfs) ||
                            dv.checkSet(ChangedFileSetHelper.NATIVE_LIBS);
                }

                // check the libraries
                if (libProjects.size() > 0) {
                    for (IProject libProject : libProjects) {
                        delta = getDelta(libProject);
                        if (delta != null) {
                            PatternBasedDeltaVisitor visitor = new PatternBasedDeltaVisitor(
                                    project, libProject,
                                    "POST:Lib");

                            ChangedFileSet libResCfs = ChangedFileSetHelper.getFullResCfs(
                                    libProject);
                            visitor.addSet(libResCfs);
                            visitor.addSet(ChangedFileSetHelper.NATIVE_LIBS);
                            // FIXME: add check on the library.jar?

                            delta.accept(visitor);

                            mPackageResources |= visitor.checkSet(libResCfs);
                            mBuildFinalPackage |= visitor.checkSet(
                                    ChangedFileSetHelper.NATIVE_LIBS);
                        }
                    }
                }

                // also go through the delta for all the referenced projects
                final int referencedCount = referencedJavaProjects.size();
                for (int i = 0 ; i < referencedCount; i++) {
                    IJavaProject referencedJavaProject = referencedJavaProjects.get(i);
                    delta = getDelta(referencedJavaProject.getProject());
                    if (delta != null) {
                        IProject referencedProject = referencedJavaProject.getProject();
                        PatternBasedDeltaVisitor visitor = new PatternBasedDeltaVisitor(
                                project, referencedProject,
                                "POST:RefedProject");

                        ChangedFileSet javaResCfs = ChangedFileSetHelper.getJavaResCfs(referencedProject);
                        visitor.addSet(javaResCfs);

                        ChangedFileSet bytecodeCfs = ChangedFileSetHelper.getByteCodeCfs(referencedProject);
                        visitor.addSet(bytecodeCfs);

                        delta.accept(visitor);

                        // save the state
                        mConvertToDex |= visitor.checkSet(bytecodeCfs);
                        mBuildFinalPackage |= visitor.checkSet(javaResCfs);
                    }
                }
            }

            // store the build status in the persistent storage
            saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex);
            saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources);
            saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);

            // Top level check to make sure the build can move forward. Only do this after recording
            // delta changes.
            abortOnBadSetup(javaProject, projectState);

            // Get the output stream. Since the builder is created for the life of the
            // project, they can be kept around.
            if (mOutStream == null) {
                mOutStream = new AndroidPrintStream(project, null /*prefix*/,
                        AdtPlugin.getOutStream());
                mErrStream = new AndroidPrintStream(project, null /*prefix*/,
                        AdtPlugin.getOutStream());
            }

            // remove older packaging markers.
            removeMarkersFromContainer(javaProject.getProject(), AdtConstants.MARKER_PACKAGING);

            // finished with the common init and tests. Special case of the library.
            if (isLibrary) {
                // check the jar output file is present, if not create it.
                IFile jarIFile = androidOutputFolder.getFile(
                        project.getName().toLowerCase() + SdkConstants.DOT_JAR);
                if (mConvertToDex == false && jarIFile.exists() == false) {
                    mConvertToDex = true;
                }

                // also update the crunch cache always since aapt does it smartly only
                // on the files that need it.
                if (DEBUG_LOG) {
                    AdtPlugin.log(IStatus.INFO, "%s running crunch!", project.getName());
                }
                BuildHelper helper = new BuildHelper(
                        projectState,
                        mBuildToolInfo,
                        mOutStream, mErrStream,
                        false /*jumbo mode doesn't matter here*/,
                        false /*dex merger doesn't matter here*/,
                        true /*debugMode*/,
                        AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE,
                        mResourceMarker);
                updateCrunchCache(project, helper);

                // refresh recursively bin/res folder
                resOutputFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);

                if (mConvertToDex) { // in this case this means some class files changed and
                                     // we need to update the jar file.
                    if (DEBUG_LOG) {
                        AdtPlugin.log(IStatus.INFO, "%s updating jar!", project.getName());
                    }

                    // resource to the AndroidManifest.xml file
                    IFile manifestFile = project.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML);
                    String appPackage = AndroidManifest.getPackage(new IFileWrapper(manifestFile));

                    IFolder javaOutputFolder = BaseProjectHelper.getJavaOutputFolder(project);

                    writeLibraryPackage(jarIFile, project, appPackage, javaOutputFolder);
                    saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex = false);

                    // refresh the bin folder content with no recursion to update the library
                    // jar file.
                    androidOutputFolder.refreshLocal(IResource.DEPTH_ONE, monitor);

                    // Also update the projects. The only way to force recompile them is to
                    // reset the library container.
                    List<ProjectState> parentProjects = projectState.getParentProjects();
                    LibraryClasspathContainerInitializer.updateProject(parentProjects);
                }

                return allRefProjects;
            }

            // Check to see if we're going to launch or export. If not, we can skip
            // the packaging and dexing process.
            if (!args.containsKey(POST_C_REQUESTED)
                    && AdtPrefs.getPrefs().getBuildSkipPostCompileOnFileSave()) {
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                        Messages.Skip_Post_Compiler);
                return allRefProjects;
            } else {
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                        Messages.Start_Full_Post_Compiler);
            }

            // first thing we do is check that the SDK directory has been setup.
            String osSdkFolder = AdtPlugin.getOsSdkFolder();

            if (osSdkFolder.length() == 0) {
                // this has already been checked in the precompiler. Therefore,
                // while we do have to cancel the build, we don't have to return
                // any error or throw anything.
                return allRefProjects;
            }

            // do some extra check, in case the output files are not present. This
            // will force to recreate them.
            IResource tmp = null;

            if (mPackageResources == false) {
                // check the full resource package
                tmp = androidOutputFolder.findMember(AdtConstants.FN_RESOURCES_AP_);
                if (tmp == null || tmp.exists() == false) {
                    mPackageResources = true;
                }
            }

            // check classes.dex is present. If not we force to recreate it.
            if (mConvertToDex == false) {
                tmp = androidOutputFolder.findMember(SdkConstants.FN_APK_CLASSES_DEX);
                if (tmp == null || tmp.exists() == false) {
                    mConvertToDex = true;
                }
            }

            // also check the final file(s)!
            String finalPackageName = ProjectHelper.getApkFilename(project, null /*config*/);
            if (mBuildFinalPackage == false) {
                tmp = androidOutputFolder.findMember(finalPackageName);
                if (tmp == null || (tmp instanceof IFile &&
                        tmp.exists() == false)) {
                    String msg = String.format(Messages.s_Missing_Repackaging, finalPackageName);
                    AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg);
                    mBuildFinalPackage = true;
                }
            }

            // at this point we know if we need to recreate the temporary apk
            // or the dex file, but we don't know if we simply need to recreate them
            // because they are missing

            // refresh the output directory first
            IContainer ic = androidOutputFolder.getParent();
            if (ic != null) {
                ic.refreshLocal(IResource.DEPTH_ONE, monitor);
            }

            // we need to test all three, as we may need to make the final package
            // but not the intermediary ones.
            if (mPackageResources || mConvertToDex || mBuildFinalPackage) {
                String forceJumboStr = projectState.getProperty(
                        AdtConstants.DEX_OPTIONS_FORCEJUMBO);
                Boolean jumbo = Boolean.valueOf(forceJumboStr);

                String dexMergerStr = projectState.getProperty(
                        AdtConstants.DEX_OPTIONS_DISABLE_MERGER);
                Boolean dexMerger = Boolean.valueOf(dexMergerStr);

                BuildHelper helper = new BuildHelper(
                        projectState,
                        mBuildToolInfo,
                        mOutStream, mErrStream,
                        jumbo.booleanValue(),
                        dexMerger.booleanValue(),
                        true /*debugMode*/,
                        AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE,
                        mResourceMarker);

                IPath androidBinLocation = androidOutputFolder.getLocation();
                if (androidBinLocation == null) {
                    markProject(AdtConstants.MARKER_PACKAGING, Messages.Output_Missing,
                            IMarker.SEVERITY_ERROR);
                    return allRefProjects;
                }
                String osAndroidBinPath = androidBinLocation.toOSString();

                // resource to the AndroidManifest.xml file
                IFile manifestFile = androidOutputFolder.getFile(
                        SdkConstants.FN_ANDROID_MANIFEST_XML);

                if (manifestFile == null || manifestFile.exists() == false) {
                    // mark project and exit
                    String msg = String.format(Messages.s_File_Missing,
                            SdkConstants.FN_ANDROID_MANIFEST_XML);
                    markProject(AdtConstants.MARKER_PACKAGING, msg, IMarker.SEVERITY_ERROR);
                    return allRefProjects;
                }

                // Remove the old .apk.
                // This make sure that if the apk is corrupted, then dx (which would attempt
                // to open it), will not fail.
                String osFinalPackagePath = osAndroidBinPath + File.separator + finalPackageName;
                File finalPackage = new File(osFinalPackagePath);

                // if delete failed, this is not really a problem, as the final package generation
                // handle already present .apk, and if that one failed as well, the user will be
                // notified.
                finalPackage.delete();

                // Check if we need to package the resources.
                if (mPackageResources) {
                    // also update the crunch cache always since aapt does it smartly only
                    // on the files that need it.
                    if (DEBUG_LOG) {
                        AdtPlugin.log(IStatus.INFO, "%s running crunch!", project.getName());
                    }
                    if (updateCrunchCache(project, helper) == false) {
                        return allRefProjects;
                    }

                    // refresh recursively bin/res folder
                    resOutputFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);

                    if (DEBUG_LOG) {
                        AdtPlugin.log(IStatus.INFO, "%s packaging resources!", project.getName());
                    }
                    // remove some aapt_package only markers.
                    removeMarkersFromContainer(project, AdtConstants.MARKER_AAPT_PACKAGE);

                    try {
                        helper.packageResources(manifestFile, libProjects, null /*resfilter*/,
                                0 /*versionCode */, osAndroidBinPath,
                                AdtConstants.FN_RESOURCES_AP_);
                    } catch (AaptExecException e) {
                        BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING,
                                e.getMessage(), IMarker.SEVERITY_ERROR);
                        return allRefProjects;
                    } catch (AaptResultException e) {
                        // attempt to parse the error output
                        String[] aaptOutput = e.getOutput();
                        boolean parsingError = AaptParser.parseOutput(aaptOutput, project);

                        // if we couldn't parse the output we display it in the console.
                        if (parsingError) {
                            AdtPlugin.printErrorToConsole(project, (Object[]) aaptOutput);

                            // if the exec failed, and we couldn't parse the error output (and
                            // therefore not all files that should have been marked, were marked),
                            // we put a generic marker on the project and abort.
                            BaseProjectHelper.markResource(project,
                                    AdtConstants.MARKER_PACKAGING,
                                    Messages.Unparsed_AAPT_Errors,
                                    IMarker.SEVERITY_ERROR);
                        }
                    }

                    // build has been done. reset the state of the builder
                    mPackageResources = false;

                    // and store it
                    saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources);
                }

                String classesDexPath = osAndroidBinPath + File.separator +
                        SdkConstants.FN_APK_CLASSES_DEX;

                // then we check if we need to package the .class into classes.dex
                if (mConvertToDex) {
                    if (DEBUG_LOG) {
                        AdtPlugin.log(IStatus.INFO, "%s running dex!", project.getName());
                    }
                    try {
                        Collection<String> dxInputPaths = helper.getCompiledCodePaths();

                        helper.executeDx(javaProject, dxInputPaths, classesDexPath);
                    } catch (DexException e) {
                        String message = e.getMessage();

                        AdtPlugin.printErrorToConsole(project, message);
                        BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING,
                                message, IMarker.SEVERITY_ERROR);

                        Throwable cause = e.getCause();

                        if (cause instanceof NoClassDefFoundError
                                || cause instanceof NoSuchMethodError) {
                            AdtPlugin.printErrorToConsole(project, Messages.Incompatible_VM_Warning,
                                    Messages.Requires_1_5_Error);
                        }

                        // dx failed, we return
                        return allRefProjects;
                    }

                    // build has been done. reset the state of the builder
                    mConvertToDex = false;

                    // and store it
                    saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex);
                }

                // now we need to make the final package from the intermediary apk
                // and classes.dex.
                // This is the default package with all the resources.

                try {
                    if (DEBUG_LOG) {
                        AdtPlugin.log(IStatus.INFO, "%s making final package!", project.getName());
                    }
                    helper.finalDebugPackage(
                            osAndroidBinPath + File.separator + AdtConstants.FN_RESOURCES_AP_,
                        classesDexPath, osFinalPackagePath, libProjects, mResourceMarker);
                } catch (KeytoolException e) {
                    String eMessage = e.getMessage();

                    // mark the project with the standard message
                    String msg = String.format(Messages.Final_Archive_Error_s, eMessage);
                    BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg,
                            IMarker.SEVERITY_ERROR);

                    // output more info in the console
                    AdtPlugin.printErrorToConsole(project,
                            msg,
                            String.format(Messages.ApkBuilder_JAVA_HOME_is_s, e.getJavaHome()),
                            Messages.ApkBuilder_Update_or_Execute_manually_s,
                            e.getCommandLine());

                    AdtPlugin.log(e, msg);

                    return allRefProjects;
                } catch (ApkCreationException e) {
                    String eMessage = e.getMessage();

                    // mark the project with the standard message
                    String msg = String.format(Messages.Final_Archive_Error_s, eMessage);
                    BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg,
                            IMarker.SEVERITY_ERROR);

                    AdtPlugin.log(e, msg);
                } catch (AndroidLocationException e) {
                    String eMessage = e.getMessage();

                    // mark the project with the standard message
                    String msg = String.format(Messages.Final_Archive_Error_s, eMessage);
                    BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg,
                            IMarker.SEVERITY_ERROR);
                    AdtPlugin.log(e, msg);
                } catch (NativeLibInJarException e) {
                    String msg = e.getMessage();

                    BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING,
                            msg, IMarker.SEVERITY_ERROR);

                    AdtPlugin.printErrorToConsole(project, (Object[]) e.getAdditionalInfo());
                } catch (CoreException e) {
                    // mark project and return
                    String msg = String.format(Messages.Final_Archive_Error_s, e.getMessage());
                    AdtPlugin.printErrorToConsole(project, msg);
                    BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg,
                            IMarker.SEVERITY_ERROR);
                    AdtPlugin.log(e, msg);
                } catch (DuplicateFileException e) {
                    String msg1 = String.format(
                            "Found duplicate file for APK: %1$s\nOrigin 1: %2$s\nOrigin 2: %3$s",
                            e.getArchivePath(), e.getFile1(), e.getFile2());
                    String msg2 = String.format(Messages.Final_Archive_Error_s, msg1);
                    AdtPlugin.printErrorToConsole(project, msg2);
                    BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg2,
                            IMarker.SEVERITY_ERROR);
                }

                // we are done.

                // refresh the bin folder content with no recursion.
                androidOutputFolder.refreshLocal(IResource.DEPTH_ONE, monitor);

                // build has been done. reset the state of the builder
                mBuildFinalPackage = false;

                // and store it
                saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);

                // reset the installation manager to force new installs of this project
                ApkInstallManager.getInstance().resetInstallationFor(project);

                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, getProject(),
                        "Build Success!");
            }
        } catch (AbortBuildException e) {
            return allRefProjects;
        } catch (Exception exception) {
            // try to catch other exception to actually display an error. This will be useful
            // if we get an NPE or something so that we can at least notify the user that something
            // went wrong.

            // first check if this is a CoreException we threw to cancel the build.
            if (exception instanceof CoreException) {
                if (((CoreException)exception).getStatus().getSeverity() == IStatus.CANCEL) {
                    // Project is already marked with an error. Nothing to do
                    return allRefProjects;
                }
            }

            String msg = exception.getMessage();
            if (msg == null) {
                msg = exception.getClass().getCanonicalName();
            }

            msg = String.format("Unknown error: %1$s", msg);
            AdtPlugin.logAndPrintError(exception, project.getName(), msg);
            markProject(AdtConstants.MARKER_PACKAGING, msg, IMarker.SEVERITY_ERROR);
        }

        // Benchmarking end
        if (BuildHelper.BENCHMARK_FLAG) {
            String msg = "BENCHMARK ADT: Ending PostCompilation. \n BENCHMARK ADT: Time Elapsed: " + //$NON-NLS-1$
                         ((System.nanoTime() - startBuildTime)/Math.pow(10, 6)) + "ms";              //$NON-NLS-1$
            AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg);
            // End Overall Timer
            msg = "BENCHMARK ADT: Done with everything! \n BENCHMARK ADT: Time Elapsed: " +          //$NON-NLS-1$
                  (System.nanoTime() - BuildHelper.sStartOverallTime)/Math.pow(10, 6) + "ms";        //$NON-NLS-1$
            AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg);
        }

        return allRefProjects;
    }

    private static class JarBuilder implements IArchiveBuilder {

        private static Pattern R_PATTERN = Pattern.compile("R(\\$.*)?\\.class"); //$NON-NLS-1$
        private static String BUILD_CONFIG_CLASS = "BuildConfig.class"; //$NON-NLS-1$

        private final byte[] buffer = new byte[1024];
        private final JarOutputStream mOutputStream;
        private final String mAppPackage;

        JarBuilder(JarOutputStream outputStream, String appPackage) {
            mOutputStream = outputStream;
            mAppPackage = appPackage.replace('.', '/');
        }

        public void addFile(IFile file, IFolder rootFolder) throws ApkCreationException {
            // we only package class file from the output folder
            if (SdkConstants.EXT_CLASS.equals(file.getFileExtension()) == false) {
                return;
            }

            IPath packageApp = file.getParent().getFullPath().makeRelativeTo(
                    rootFolder.getFullPath());

            String name = file.getName();
            // Ignore the library's R/Manifest/BuildConfig classes.
            if (mAppPackage.equals(packageApp.toString()) &&
                            (BUILD_CONFIG_CLASS.equals(name) ||
                            R_PATTERN.matcher(name).matches())) {
                return;
            }

            IPath path = file.getFullPath().makeRelativeTo(rootFolder.getFullPath());
            try {
                addFile(file.getContents(), file.getLocalTimeStamp(), path.toString());
            } catch (ApkCreationException e) {
                throw e;
            } catch (Exception e) {
                throw new ApkCreationException(e, "Failed to add %s", file);
            }
        }

        @Override
        public void addFile(File file, String archivePath) throws ApkCreationException,
                SealedApkException, DuplicateFileException {
            try {
                FileInputStream inputStream = new FileInputStream(file);
                long lastModified = file.lastModified();
                addFile(inputStream, lastModified, archivePath);
            } catch (ApkCreationException e) {
                throw e;
            } catch (Exception e) {
                throw new ApkCreationException(e, "Failed to add %s", file);
            }
        }

        private void addFile(InputStream content, long lastModified, String archivePath)
                throws IOException, ApkCreationException {
            // create the jar entry
            JarEntry entry = new JarEntry(archivePath);
            entry.setTime(lastModified);

            try {
                // add the entry to the jar archive
                mOutputStream.putNextEntry(entry);

                // read the content of the entry from the input stream, and write
                // it into the archive.
                int count;
                while ((count = content.read(buffer)) != -1) {
                    mOutputStream.write(buffer, 0, count);
                }
            } finally {
                try {
                    if (content != null) {
                        content.close();
                    }
                } catch (Exception e) {
                    throw new ApkCreationException(e, "Failed to close stream");
                }
            }
        }
    }

    /**
     * Updates the crunch cache if needed and return true if the build must continue.
     */
    private boolean updateCrunchCache(IProject project, BuildHelper helper) {
        try {
            helper.updateCrunchCache();
        } catch (AaptExecException e) {
            BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING,
                    e.getMessage(), IMarker.SEVERITY_ERROR);
            return false;
        } catch (AaptResultException e) {
            // attempt to parse the error output
            String[] aaptOutput = e.getOutput();
            boolean parsingError = AaptParser.parseOutput(aaptOutput, project);
            // if we couldn't parse the output we display it in the console.
            if (parsingError) {
                AdtPlugin.printErrorToConsole(project, (Object[]) aaptOutput);
            }
        }

        return true;
    }

    /**
     * Writes the library jar file.
     * @param jarIFile the destination file
     * @param project the library project
     * @param appPackage the library android package
     * @param javaOutputFolder the JDT output folder.
     */
    private void writeLibraryPackage(IFile jarIFile, IProject project, String appPackage,
            IFolder javaOutputFolder) {

        JarOutputStream jos = null;
        try {
            Manifest manifest = new Manifest();
            Attributes mainAttributes = manifest.getMainAttributes();
            mainAttributes.put(Attributes.Name.CLASS_PATH, "Android ADT"); //$NON-NLS-1$
            mainAttributes.putValue("Created-By", "1.0 (Android)"); //$NON-NLS-1$  //$NON-NLS-2$
            jos = new JarOutputStream(
                    new FileOutputStream(jarIFile.getLocation().toFile()), manifest);

            JarBuilder jarBuilder = new JarBuilder(jos, appPackage);

            // write the class files
            writeClassFilesIntoJar(jarBuilder, javaOutputFolder, javaOutputFolder);

            // now write the standard Java resources from the output folder
            ApkBuilder.addSourceFolder(jarBuilder, javaOutputFolder.getLocation().toFile());

            saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex);
        } catch (Exception e) {
            AdtPlugin.log(e, "Failed to write jar file %s", jarIFile.getLocation().toOSString());
        } finally {
            if (jos != null) {
                try {
                    jos.close();
                } catch (IOException e) {
                    // pass
                }
            }
        }
    }

    private void writeClassFilesIntoJar(JarBuilder builder, IFolder folder, IFolder rootFolder)
            throws CoreException, IOException, ApkCreationException {
        IResource[] members = folder.members();
        for (IResource member : members) {
            if (member.getType() == IResource.FOLDER) {
                writeClassFilesIntoJar(builder, (IFolder) member, rootFolder);
            } else if (member.getType() == IResource.FILE) {
                IFile file = (IFile) member;
                builder.addFile(file, rootFolder);
            }
        }
    }

    @Override
    protected void startupOnInitialize() {
        super.startupOnInitialize();

        // load the build status. We pass true as the default value to
        // force a recompile in case the property was not found
        mConvertToDex = loadProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, true);
        mPackageResources = loadProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, true);
        mBuildFinalPackage = loadProjectBooleanProperty(PROPERTY_BUILD_APK, true);
    }

    @Override
    protected void abortOnBadSetup(
            @NonNull IJavaProject javaProject,
            @Nullable ProjectState projectState) throws AbortBuildException, CoreException {
        super.abortOnBadSetup(javaProject, projectState);

        IProject iProject = getProject();

        // do a (hopefully quick) search for Precompiler type markers. Those are always only
        // errors.
        stopOnMarker(iProject, AdtConstants.MARKER_AAPT_COMPILE, IResource.DEPTH_INFINITE,
                false /*checkSeverity*/);
        stopOnMarker(iProject, AdtConstants.MARKER_AIDL, IResource.DEPTH_INFINITE,
                false /*checkSeverity*/);
        stopOnMarker(iProject, AdtConstants.MARKER_RENDERSCRIPT, IResource.DEPTH_INFINITE,
                false /*checkSeverity*/);
        stopOnMarker(iProject, AdtConstants.MARKER_ANDROID, IResource.DEPTH_ZERO,
                false /*checkSeverity*/);

        // do a search for JDT markers. Those can be errors or warnings
        stopOnMarker(iProject, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,
                IResource.DEPTH_INFINITE, true /*checkSeverity*/);
        stopOnMarker(iProject, IJavaModelMarker.BUILDPATH_PROBLEM_MARKER,
                IResource.DEPTH_INFINITE, true /*checkSeverity*/);
    }
}
