/*
 * Autopsy Forensic Browser
 * 
 * Copyright 2013 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.imagegallery.actions;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Menu;
import javax.swing.SwingWorker;
import org.openide.util.Utilities;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.imagegallery.FileIDSelectionModel;
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableTagsManager;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;

/**
 * Instances of this Action allow users to apply tags to content.
 *
 * //TODO: since we are not using actionsGlobalContext anymore and this has
 * diverged from autopsy action, make this extend from controlsfx Action
 */
public class AddDrawableTagAction extends AddTagAction {

    private static final Logger LOGGER = Logger.getLogger(AddDrawableTagAction.class.getName());

    private final ImageGalleryController controller;

    public AddDrawableTagAction(ImageGalleryController controller) {
        this.controller = controller;
    }

    public Menu getPopupMenu() {
        return new TagMenu(controller);
    }

    @Override
    protected String getActionDisplayName() {
        return Utilities.actionsGlobalContext().lookupAll(AbstractFile.class).size() > 1 ? "Tag Files" : "Tag File";
    }

    @Override
    public void addTag(TagName tagName, String comment) {
        Set<Long> selectedFiles = new HashSet<>(FileIDSelectionModel.getInstance().getSelected());
        addTagsToFiles(tagName, comment, selectedFiles);
    }

    @Override
    public void addTagsToFiles(TagName tagName, String comment, Set<Long> selectedFiles) {
        new SwingWorker<Void, Void>() {

            @Override
            protected Void doInBackground() throws Exception {
                for (Long fileID : selectedFiles) {
                    try {
                        final DrawableFile<?> file = controller.getFileFromId(fileID);
                        LOGGER.log(Level.INFO, "tagging {0} with {1} and comment {2}", new Object[]{file.getName(), tagName.getDisplayName(), comment});

                        // check if the same tag is being added for the same abstract file.
                        DrawableTagsManager tagsManager = controller.getTagsManager();
                        List<ContentTag> contentTags = tagsManager.getContentTagsByContent(file);
                        Optional<TagName> duplicateTagName = contentTags.stream()
                                .map(ContentTag::getName)
                                .filter(tagName::equals)
                                .findAny();

                        if (duplicateTagName.isPresent()) {
                            Platform.runLater(() -> {
                                Alert alert = new Alert(Alert.AlertType.WARNING, "Unable to tag " + file.getName() + ". It has already been tagged as \"" + tagName.getDisplayName() + ". Cannot reapply the same tag.", ButtonType.OK);
                                alert.setHeaderText("Tag Error");
                                alert.show();
                            });
                        } else {
                            controller.getTagsManager().addContentTag(file, tagName, comment);
                        }

                    } catch (TskCoreException tskCoreException) {
                        LOGGER.log(Level.SEVERE, "Error tagging result", tskCoreException);
                        Platform.runLater(() -> {
                            new Alert(Alert.AlertType.ERROR, "Unable to file " + fileID + ".").show();
                        });
                    }
                }
                return null;
            }

            @Override
            protected void done() {
                super.done();
                try {
                    get();
                } catch (InterruptedException | ExecutionException ex) {
                    LOGGER.log(Level.SEVERE, "unexpected exception while tagging files", ex);
                }
            }
        }.execute();
    }
}

@@ -45,16 +45,19 @@
 ght 2013
+-15
  Basis T
@@ -988,48 +988,8 @@
 rt;%0A
-import javafx.scene.control.ButtonType;%0A
 impo
@@ -3789,443 +3789,290 @@
     
-Platform.runLater(() -%3E %7B%0A                                Alert alert = new Alert(Alert.AlertType.WARNING, %22Unable to tag %22 + file.getName() + %22. It has already been tagged as %5C%22%22 + tagName.getDisplayName() + %22. Cannot reapply the same tag.%22, ButtonType.OK);%0A                                alert.setHeaderText(%22Tag Error%22);%0A                                alert.show();%0A                            %7D);%0A                        %7D else %7B
+LOGGER.log(Level.INFO, %22%7B0%7D already tagged as %7B1%7D. Skipping.%22, new Object%5B%5D%7Bfile.getName(), tagName.getDisplayName()%7D);%0A                        %7D else %7B%0A                            LOGGER.log(Level.INFO, %22Tagging %7B0%7D as %7B1%7D%22, new Object%5B%5D%7Bfile.getName(), tagName.getDisplayName()%7D);
 %0A   
@@ -4324,14 +4324,12 @@
 ing 
-result
+file
 %22, t
@@ -4468,16 +4468,20 @@
 able to 
+tag 
 file %22 +

remove the dialog informing the user about duplicate tags as it provides little value, and can overwhelm the UI