/*
 * Copyright (C) 2010 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.actions;

import com.android.SdkConstants;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.BuildToolInfo;
import com.android.utils.GrabProcessOutput;
import com.android.utils.GrabProcessOutput.IProcessOutput;
import com.android.utils.GrabProcessOutput.Wait;
import com.android.utils.SdkUtils;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;

/**
 * Runs dexdump on the classes.dex of a selected project.
 */
public class DexDumpAction implements IObjectActionDelegate {

    private ISelection mSelection;

    @Override
    public void setActivePart(IAction action, IWorkbenchPart targetPart) {
        // pass
    }

    @Override
    public void run(IAction action) {
        if (mSelection instanceof IStructuredSelection) {
            for (Iterator<?> it = ((IStructuredSelection)mSelection).iterator(); it.hasNext();) {
                Object element = it.next();
                IProject project = null;
                if (element instanceof IProject) {
                    project = (IProject)element;
                } else if (element instanceof IAdaptable) {
                    project = (IProject)((IAdaptable)element).getAdapter(IProject.class);
                }
                if (project != null) {
                    dexDumpProject(project);
                }
            }
        }
    }

    @Override
    public void selectionChanged(IAction action, ISelection selection) {
        mSelection = selection;
    }

    /**
     * Calls {@link #runDexDump(IProject, IProgressMonitor)} inside a job.
     *
     * @param project on which to run dexdump.
     */
    private void dexDumpProject(final IProject project) {
        new Job("Dexdump") {
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                return runDexDump(project, monitor);
            }
        }.schedule();
    }

    /**
     * Runs <code>dexdump</code> on the classex.dex of the project.
     * Saves the output in a temporary file.
     * On success, opens the file in the default text editor.
     *
     * @param project on which to run dexdump.
     * @param monitor The job's monitor.
     */
    private IStatus runDexDump(final IProject project, IProgressMonitor monitor) {
        File dstFile = null;
        boolean removeDstFile = true;
        try {
            if (monitor != null) {
                monitor.beginTask(String.format("Dump dex of %1$s", project.getName()), 2);
            }

            Sdk current = Sdk.getCurrent();
            if (current == null) {
                AdtPlugin.printErrorToConsole(project,
                        "DexDump: missing current SDK");                            //$NON-NLS-1$
                return Status.OK_STATUS;
            }

            BuildToolInfo buildToolInfo = current.getLatestBuildTool();
            if (buildToolInfo == null) {
                AdtPlugin.printErrorToConsole(project,
                    "SDK missing build tools. Please install build tools using SDK Manager.");
                return Status.OK_STATUS;
            }

            File buildToolsFolder = buildToolInfo.getLocation();
            File dexDumpFile = new File(buildToolsFolder, SdkConstants.FN_DEXDUMP);

            IPath binPath = project.getFolder(SdkConstants.FD_OUTPUT).getLocation();
            if (binPath == null) {
                AdtPlugin.printErrorToConsole(project,
                    "DexDump: missing project /bin folder. Please compile first."); //$NON-NLS-1$
                return Status.OK_STATUS;
            }

            File classesDexFile =
                new File(binPath.toOSString(), SdkConstants.FN_APK_CLASSES_DEX);
            if (!classesDexFile.exists()) {
                AdtPlugin.printErrorToConsole(project,
                    "DexDump: missing classex.dex for project. Please compile first.");//$NON-NLS-1$
                return Status.OK_STATUS;
            }

            try {
                dstFile = File.createTempFile(
                        "dexdump_" + project.getName() + "_",         //$NON-NLS-1$ //$NON-NLS-2$
                        ".txt");                                                    //$NON-NLS-1$
            } catch (Exception e) {
                AdtPlugin.logAndPrintError(e, project.getName(),
                        "DexDump: createTempFile failed.");                         //$NON-NLS-1$
                return Status.OK_STATUS;
            }

            // --- Exec command line and save result to dst file

            String[] command = new String[2];
            command[0] = dexDumpFile.getAbsolutePath();
            command[1] = classesDexFile.getAbsolutePath();

            try {
                final Process process = Runtime.getRuntime().exec(command);

                final BufferedWriter writer = new BufferedWriter(new FileWriter(dstFile));
                try {
                    final String lineSep = SdkUtils.getLineSeparator();

                    int err = GrabProcessOutput.grabProcessOutput(
                            process,
                            Wait.WAIT_FOR_READERS,
                            new IProcessOutput() {
                                @Override
                                public void out(@Nullable String line) {
                                    if (line != null) {
                                        try {
                                            writer.write(line);
                                            writer.write(lineSep);
                                        } catch (IOException ignore) {}
                                    }
                                }

                                @Override
                                public void err(@Nullable String line) {
                                    if (line != null) {
                                        AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE,
                                                project, line);
                                    }
                                }
                            });

                    if (err == 0) {
                        // The command worked. In this case we don't remove the
                        // temp file in the finally block.
                        removeDstFile = false;
                    } else {
                        AdtPlugin.printErrorToConsole(project,
                            "DexDump failed with code " + Integer.toString(err));       //$NON-NLS-1$
                        return Status.OK_STATUS;
                    }
                } finally {
                    writer.close();
                }
            } catch (InterruptedException e) {
                // ?
            }

            if (monitor != null) {
                monitor.worked(1);
            }

            // --- Open the temp file in an editor

            final String dstPath = dstFile.getAbsolutePath();
            AdtPlugin.getDisplay().asyncExec(new Runnable() {
                @Override
                public void run() {
                    IFileStore fileStore =
                        EFS.getLocalFileSystem().getStore(new Path(dstPath));
                    if (!fileStore.fetchInfo().isDirectory() &&
                            fileStore.fetchInfo().exists()) {

                        IWorkbench wb = PlatformUI.getWorkbench();
                        IWorkbenchWindow win = wb == null ? null : wb.getActiveWorkbenchWindow();
                        final IWorkbenchPage page = win == null ? null : win.getActivePage();

                        if (page != null) {
                            try {
                                IDE.openEditorOnFileStore(page, fileStore);
                            } catch (PartInitException e) {
                                AdtPlugin.logAndPrintError(e, project.getName(),
                                "Opening DexDump result failed. Result is available at %1$s", //$NON-NLS-1$
                                dstPath);
                            }
                        }
                    }
                }
            });

            if (monitor != null) {
                monitor.worked(1);
            }

            return Status.OK_STATUS;

        } catch (IOException e) {
            AdtPlugin.logAndPrintError(e, project.getName(),
                    "DexDump failed.");                                     //$NON-NLS-1$
            return Status.OK_STATUS;

        } finally {
            // By default we remove the temp file on failure.
            if (removeDstFile && dstFile != null) {
                try {
                    dstFile.delete();
                } catch (Exception e) {
                    AdtPlugin.logAndPrintError(e, project.getName(),
                            "DexDump: can't delete temp file %1$s.",        //$NON-NLS-1$
                            dstFile.getAbsoluteFile());
                }
            }
            if (monitor != null) {
                monitor.done();
            }
        }
    }
}
