package org.ovirt.engine.core.bll.tasks;

import org.ovirt.engine.core.common.asynctasks.AsyncTaskType;
import org.ovirt.engine.core.common.businessentities.CommandEntity;
import org.ovirt.engine.core.compat.CommandStatus;
import org.ovirt.engine.core.compat.DateTime;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.TransactionScopeOption;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;
import org.ovirt.engine.core.utils.transaction.TransactionMethod;
import org.ovirt.engine.core.utils.transaction.TransactionSupport;

import java.util.List;
import java.util.Set;

public class CommandsCacheImpl implements CommandsCache {

    private static final String COMMAND_MAP_NAME = "commandMap";
    CacheWrapper<Guid, CommandEntity> commandMap;
    private volatile boolean cacheInitialized;
    private Object LOCK = new Object();

    public CommandsCacheImpl() {
        commandMap = CacheProviderFactory.<Guid, CommandEntity> getCacheWrapper(COMMAND_MAP_NAME);
    }

    private void initializeCache() {
        if (!cacheInitialized) {
            synchronized(LOCK) {
                if (!cacheInitialized) {
                    List<CommandEntity> cmdEntities = DbFacade.getInstance().getCommandEntityDao().getAll();
                    for (CommandEntity cmdEntity : cmdEntities) {
                        commandMap.put(cmdEntity.getId(), cmdEntity);
                    }
                    cacheInitialized = true;
                }
            }
        }
    }

    public Set<Guid> keySet() {
        initializeCache();
        return commandMap.keySet();
    }

    @Override
    public CommandEntity get(Guid commandId) {
        initializeCache();
        return commandMap.get(commandId);
    }

    @Override
    public void remove(final Guid commandId) {
        commandMap.remove(commandId);
        TransactionSupport.executeInScope(TransactionScopeOption.Required, new TransactionMethod<Object>() {

            @Override
            public Void runInTransaction() {
                DbFacade.getInstance().getCommandEntityDao().remove(commandId);
                return null;
            }
        });

    }

    @Override
    public void put(final CommandEntity cmdEntity) {
        commandMap.put(cmdEntity.getId(), cmdEntity);
        TransactionSupport.executeInScope(TransactionScopeOption.Required, new TransactionMethod<Object>() {

            @Override
            public Void runInTransaction() {
                DbFacade.getInstance().getCommandEntityDao().saveOrUpdate(cmdEntity);
                return null;
            }
        });
    }

    public void removeAllCommandsBeforeDate(DateTime cutoff) {
        DbFacade.getInstance().getCommandEntityDao().removeAllBeforeDate(cutoff);
        cacheInitialized = false;
        initializeCache();
    }

    public void updateCommandStatus(Guid commandId, AsyncTaskType taskType, CommandStatus status) {
        final CommandEntity cmdEntity = get(commandId);
        if (cmdEntity != null) {
            cmdEntity.setCommandStatus(status);
            if (taskType.equals(AsyncTaskType.notSupported) || cmdEntity.isCallBackEnabled()) {
                TransactionSupport.executeInScope(TransactionScopeOption.Required, new TransactionMethod<Object>() {

                    @Override
                    public Void runInTransaction() {
                        DbFacade.getInstance().getCommandEntityDao().saveOrUpdate(cmdEntity);
                        return null;
                    }
                });
            }
        }
    }


    public void updateCallBackNotified(final Guid commandId) {
        CommandEntity cmdEntity = get(commandId);
        if (cmdEntity != null) {
            cmdEntity.setCallBackNotified(true);
            TransactionSupport.executeInScope(TransactionScopeOption.Required, new TransactionMethod<Void>() {
                @Override
                public Void runInTransaction() {
                    DbFacade.getInstance().getCommandEntityDao().updateNotified(commandId);
                    return null;
                }
            });
        }
    }
}

@@ -35,16 +35,62 @@
 tasks;%0A%0A
+import java.util.List;%0Aimport java.util.Set;%0A%0A
 import o
@@ -383,268 +383,29 @@
 ore.
-compat.TransactionScopeOption;%0Aimport org.ovirt.engine.core.dal.dbbroker.DbFacade;%0Aimport org.ovirt.engine.core.utils.transaction.TransactionMethod;%0Aimport org.ovirt.engine.core.utils.transaction.TransactionSupport;%0A%0Aimport java.util.List;%0Aimport java.util.Set
+dal.dbbroker.DbFacade
 ;%0A%0Ap
@@ -1651,193 +1651,8 @@
 d);%0A
-        TransactionSupport.executeInScope(TransactionScopeOption.Required, new TransactionMethod%3CObject%3E() %7B%0A%0A            @Override%0A            public Void runInTransaction() %7B%0A        
     
@@ -1723,64 +1723,8 @@
 d);%0A
-                return null;%0A            %7D%0A        %7D);%0A%0A
     
@@ -1851,193 +1851,8 @@
 y);%0A
-        TransactionSupport.executeInScope(TransactionScopeOption.Required, new TransactionMethod%3CObject%3E() %7B%0A%0A            @Override%0A            public Void runInTransaction() %7B%0A        
     
@@ -1929,63 +1929,8 @@
 y);%0A
-                return null;%0A            %7D%0A        %7D);%0A
     
@@ -2498,363 +2498,75 @@
     
-TransactionSupport.executeInScope(TransactionScopeOption.Required, new TransactionMethod%3CObject%3E() %7B%0A%0A                    @Override%0A                    public Void runInTransaction() %7B%0A                        DbFacade.getInstance().getCommandEntityDao().saveOrUpdate(cmdEntity);%0A                        return null;%0A                    %7D%0A                %7D
+DbFacade.getInstance().getCommandEntityDao().saveOrUpdate(cmdEntity
 );%0A 
@@ -2795,202 +2795,8 @@
 e);%0A
-            TransactionSupport.executeInScope(TransactionScopeOption.Required, new TransactionMethod%3CVoid%3E() %7B%0A                @Override%0A                public Void runInTransaction() %7B%0A        
     
@@ -2879,75 +2879,8 @@
 d);%0A
-                    return null;%0A                %7D%0A            %7D);%0A
     

remove redundant transactions (CoCo cleanup)