package edu.harvard.iq.dataverse.engine.command.impl;

import edu.harvard.iq.dataverse.DataFile;
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.DatasetVersionUser;
import edu.harvard.iq.dataverse.Dataverse;
import edu.harvard.iq.dataverse.authorization.DataverseRole;
import edu.harvard.iq.dataverse.IndexServiceBean;
import edu.harvard.iq.dataverse.RoleAssignment;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.users.User;
import edu.harvard.iq.dataverse.engine.command.AbstractVoidCommand;
import edu.harvard.iq.dataverse.engine.command.CommandContext;
import edu.harvard.iq.dataverse.engine.command.RequiredPermissions;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import java.util.Iterator;

/**
 * Same as {@link DeleteDatasetCommand}, but does not stop it the dataset is
 * published. This command is reserved for super-users, if at all.
 *
 * @author michael
 */
@RequiredPermissions(Permission.DestructiveEdit)
public class DestroyDatasetCommand extends AbstractVoidCommand {

    private final Dataset doomed;

    public DestroyDatasetCommand(Dataset doomed, User aUser) {
        super(aUser, doomed);
        this.doomed = doomed;
    }

    @Override
    protected void executeImpl(CommandContext ctxt) throws CommandException {

        final Dataset managedDoomed = ctxt.em().merge(doomed);

        // ASSIGNMENTS
        for (RoleAssignment ra : ctxt.roles().directRoleAssignments(doomed)) {
            ctxt.em().remove(ra);
        }
        // ROLES
        for (DataverseRole ra : ctxt.roles().findByOwnerId(doomed.getId())) {
            ctxt.em().remove(ra);
        }

        // files need to iterate through and remove 'by hand' to avoid
        // optimistic lock issues....
        
        Iterator <DataFile> dfIt = doomed.getFiles().iterator();
        while (dfIt.hasNext()){
            DataFile df = dfIt.next();
            ctxt.engine().submit(new DeleteDataFileCommand(df, getUser()));
            dfIt.remove();
        }
        
        // version users and versions 
        for (DatasetVersion ver : managedDoomed.getVersions()) {
            for (DatasetVersionUser ddu : ver.getDatasetVersionDataverseUsers()) {
                ctxt.em().remove(ddu);
            }
            ctxt.em().remove(ver);
        }
        /* commented out because handled above
         -- not sure the reason for the merge
         doesn't seem to be needed in above code
         for ( DatasetVersion ver : managedDoomed.getVersions() ) {
         DatasetVersion managed = ctxt.em().merge(ver);
         ctxt.em().remove( managed );
         }*/

        Dataverse toReIndex = managedDoomed.getOwner();

        // dataset
        ctxt.em().remove(managedDoomed);

        //remove from index
        String indexingResult = ctxt.index().removeSolrDocFromIndex(IndexServiceBean.solrDocIdentifierDataset + doomed.getId() + IndexServiceBean.draftSuffix);

        ctxt.index().indexDataverse(toReIndex);
    }

}

@@ -487,24 +487,95 @@
 Permission;%0A
+import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;%0A
 import edu.h
@@ -616,24 +616,24 @@
 users.User;%0A
-
 import edu.h
@@ -755,76 +755,8 @@
 xt;%0A
-import edu.harvard.iq.dataverse.engine.command.RequiredPermissions;%0A
 impo
@@ -822,24 +822,132 @@
 dException;%0A
+import edu.harvard.iq.dataverse.engine.command.exception.PermissionException;%0Aimport java.util.Collections;%0A
 import java.
@@ -960,16 +960,38 @@
 terator;
+%0Aimport java.util.Set;
 %0A%0A/**%0A *
@@ -1158,16 +1158,133 @@
 ael%0A */%0A
+// No permission check as destory currently works outside the permission system%0A// (user is checked for superuser)%0A//
 @Require
@@ -1324,16 +1324,16 @@
 veEdit)%0A
-
 public c
@@ -1423,16 +1423,45 @@
  doomed;
+%0A    private final User user;
 %0A%0A    pu
@@ -1573,24 +1573,51 @@
 d = doomed;%0A
+        this.user = aUser;%0A
     %7D%0A%0A    @
@@ -1700,24 +1700,387 @@
 xception %7B%0A%0A
+        if (user instanceof AuthenticatedUser) %7B%0A            if (((AuthenticatedUser) user).isSuperuser()) %7B%0A                Set%3CPermission%3E returnSet = Collections.emptySet();%0A                throw new PermissionException(%22Destroy can only be called by superusers.%22,%0A                    this, returnSet, doomed);                %0A            %7D%0A        %7D%0A        %0A
         fina

use new, simplified permissions (destroy is outside permissions, checks for superuser)