/*
 * Autopsy Forensic Browser
 * 
 * Copyright 2011-2016 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> org
 * 
 * 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 org.sleuthkit.autopsy.directorytree;

import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.JOptionPane;
import org.openide.nodes.Node;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils;

/**
 * Extracts a File object to a temporary file in the case directory, and then
 * tries to open it in the user's system with the default or user specified
 * associated application.
 */
public class ExternalViewerAction extends AbstractAction {

    private final static Logger logger = Logger.getLogger(ExternalViewerAction.class.getName());
    private org.sleuthkit.datamodel.AbstractFile fileObject;
    private String fileObjectExt;
    final static String[] EXECUTABLE_EXT = {".exe", ".dll", ".com", ".bat", ".msi", ".reg", ".scr", ".cmd"}; //NON-NLS

    public ExternalViewerAction(String title, Node fileNode) {
        super(title);
        this.fileObject = fileNode.getLookup().lookup(org.sleuthkit.datamodel.AbstractFile.class);

        long size = fileObject.getSize();
        String fileName = fileObject.getName();
        int extPos = fileName.lastIndexOf('.');

        boolean isExecutable = false;
        if (extPos != -1) {
            String extension = fileName.substring(extPos, fileName.length()).toLowerCase();
            fileObjectExt = extension;
            for (int i = 0; i < EXECUTABLE_EXT.length; ++i) {
                if (EXECUTABLE_EXT[i].equals(extension)) {
                    isExecutable = true;
                    break;
                }
            }
        } else {
            fileObjectExt = "";
        }

        // no point opening a file if it's empty, and java doesn't know how to
        // find an application for files without an extension
        // or if file is executable (for security reasons)
        if (!(size > 0) || extPos == -1 || isExecutable) {
            this.setEnabled(false);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // Get the temp folder path of the case
        String tempPath = Case.getCurrentCase().getTempDirectory();
        tempPath = tempPath + File.separator + this.fileObject.getName();

        // create the temporary file
        File tempFile = new File(tempPath);
        if (tempFile.exists()) {
            tempFile.delete();
        }
        try {
            tempFile.createNewFile();
            ContentUtils.writeToFile(fileObject, tempFile);
        } catch (IOException ex) {
            logger.log(Level.WARNING, "Can't save to temporary file.", ex); //NON-NLS
        }

        ExternalViewerAction.openFile(fileObject.getMIMEType(), fileObjectExt, tempFile);

        // delete the temporary file on exit
        tempFile.deleteOnExit();
    }

    /**
     * Opens a file, taking into account user preferences and then the default
     * associated application.
     *
     * @param mimeType MIME type of the file
     * @param ext      extension of the file
     * @param file     the file object
     */
    @Messages({
        "ExternalViewerAction.actionPerformed.failure.title=Open File Failure",
        "ExternalViewerAction.actionPerformed.failure.IO.message=There is no associated editor for files of this type or the associated application failed to launch.",
        "ExternalViewerAction.actionPerformed.failure.support.message=This platform (operating system) does not support opening a file in an editor this way.",
        "ExternalViewerAction.actionPerformed.failure.missingFile.message=The file no longer exists.",
        "ExternalViewerAction.actionPerformed.failure.permission.message=Permission to open the file was denied."})
    public static void openFile(String mimeType, String ext, File file) {
        /**
         * Check if the file MIME type or extension exists in the user defined
         * settings. Otherwise open with the default associated application.
         */
        String exePath = ExternalViewerRulesManager.getInstance().getExePathForName(mimeType);
        if (exePath.equals("")) {
            exePath = ExternalViewerRulesManager.getInstance().getExePathForName(ext);
        }
        if (!exePath.equals("")) {
            Runtime runtime = Runtime.getRuntime();
            String[] s = new String[]{exePath, file.getAbsolutePath()};
            try {
                runtime.exec(s);
            } catch (IOException ex) {
                logger.log(Level.WARNING, "Could not open the specified viewer for the given file: " + file.getName(), ex); //NON-NLS
                JOptionPane.showMessageDialog(null, Bundle.ExternalViewerAction_actionPerformed_failure_message(), Bundle.ExternalViewerAction_actionPerformed_failure_title(), JOptionPane.ERROR_MESSAGE);
            }
        } else {
            try {
                Desktop.getDesktop().open(file);
            } catch (IOException ex) {
                logger.log(Level.WARNING, "Could not find a viewer for the given file: " + file.getName(), ex); //NON-NLS
                JOptionPane.showMessageDialog(null,
                        Bundle.ExternalViewerAction_actionPerformed_failure_IO_message(),
                        Bundle.ExternalViewerAction_actionPerformed_failure_title(),
                        JOptionPane.ERROR_MESSAGE);
            } catch (UnsupportedOperationException ex) {
                logger.log(Level.WARNING, "Platform cannot open " + file.getName() + " in the defined editor.", ex); //NON-NLS
                JOptionPane.showMessageDialog(null,
                        Bundle.ExternalViewerAction_actionPerformed_failure_support_message(),
                        Bundle.ExternalViewerAction_actionPerformed_failure_title(),
                        JOptionPane.ERROR_MESSAGE);
            } catch (IllegalArgumentException ex) {
                logger.log(Level.WARNING, "Could not find the given file: " + file.getName(), ex); //NON-NLS
                JOptionPane.showMessageDialog(null,
                        Bundle.ExternalViewerAction_actionPerformed_failure_missingFile_message(),
                        Bundle.ExternalViewerAction_actionPerformed_failure_title(),
                        JOptionPane.ERROR_MESSAGE);
            } catch (SecurityException ex) {
                logger.log(Level.WARNING, "Could not get permission to open the given file: " + file.getName(), ex); //NON-NLS
                JOptionPane.showMessageDialog(null,
                        Bundle.ExternalViewerAction_actionPerformed_failure_permission_message(),
                        Bundle.ExternalViewerAction_actionPerformed_failure_title(),
                        JOptionPane.ERROR_MESSAGE);
            }
        }
    }

}

@@ -5535,16 +5535,19 @@
 failure_
+IO_
 message(

Fix bundle message