// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License.  Citrix Systems, Inc.
// reserves all rights not expressly granted by 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.
// 
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.cluster;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.ejb.Local;
import javax.naming.ConfigurationException;

import org.apache.log4j.Logger;

import com.cloud.cluster.dao.StackMaidDao;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.serializer.SerializerHelper;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GlobalLock;

@Local(value=CheckPointManager.class)
public class CheckPointManagerImpl implements CheckPointManager, Manager, ClusterManagerListener {
    private static final Logger s_logger = Logger.getLogger(CheckPointManagerImpl.class);

    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3; // 3 seconds
    private int _cleanupRetryInterval;

    private String _name;

    @Inject
    private StackMaidDao _maidDao;

    @Inject
    private ClusterManager _clusterMgr;
    
    long _msId;

    private final ScheduledExecutorService _cleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Task-Cleanup"));
    
    protected CheckPointManagerImpl() {
    }

    @Override
    public boolean configure(String name, Map<String, Object> xmlParams) throws ConfigurationException {
        _name = name;

        if (s_logger.isInfoEnabled()) {
            s_logger.info("Start configuring StackMaidManager : " + name);
        }

        StackMaid.init(ManagementServerNode.getManagementServerId());
        _msId = ManagementServerNode.getManagementServerId();

        _clusterMgr.registerListener(this);
        
        ComponentLocator locator = ComponentLocator.getCurrentLocator();
        ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
        
        Map<String, String> params = configDao.getConfiguration(xmlParams);
        
        _cleanupRetryInterval = NumbersUtil.parseInt(params.get(Config.TaskCleanupRetryInterval.key()), 600);
        _maidDao.takeover(_msId, _msId);
        return true;
    }

    private void cleanupLeftovers(List<CheckPointVO> l) {
        for (CheckPointVO maid : l) {
            if (StackMaid.doCleanup(maid)) {
                _maidDao.expunge(maid.getId());
            }
        }
    }
    
    @Override
	public void onManagementNodeIsolated() {
	}

    @DB
    private Runnable getGCTask() {
        return new Runnable() {
            @Override
            public void run() {
                GlobalLock scanLock = GlobalLock.getInternLock("StackMaidManagerGC");
                try {
                    if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
                        try {
                            reallyRun();
                        } finally {
                            scanLock.unlock();
                        }
                    }
                } finally {
                    scanLock.releaseRef();
                }
            }

            public void reallyRun() {
                try {
                    Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - 7200000);
                    List<CheckPointVO> l = _maidDao.listLeftoversByCutTime(cutTime);
                    cleanupLeftovers(l);
                } catch (Throwable e) {
                    s_logger.error("Unexpected exception when trying to execute queue item, ", e);
                }
            }
        };
    }

    @Override
    public boolean start() {
        _cleanupScheduler.schedule(new CleanupTask(), _cleanupRetryInterval > 0 ? _cleanupRetryInterval : 600, TimeUnit.SECONDS);
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    @Override
    public String getName() {
        return _name;
    }

    @Override
    public void onManagementNodeJoined(List<ManagementServerHostVO> nodeList, long selfNodeId) {
        // Nothing to do
    }

    @Override
    public void onManagementNodeLeft(List<ManagementServerHostVO> nodeList, long selfNodeId) {
        for (ManagementServerHostVO node : nodeList) {
            if (_maidDao.takeover(node.getMsid(), selfNodeId)) {
                s_logger.info("Taking over from " + node.getMsid());
                _cleanupScheduler.execute(new CleanupTask());
            }
        }
    }
    
    @Override
    @DB
    public long pushCheckPoint(CleanupMaid context) {
        long seq =  _maidDao.pushCleanupDelegate(_msId, 0, context.getClass().getName(), context);
        return seq;
    }

    @Override
    @DB
    public void updateCheckPointState(long taskId, CleanupMaid updatedContext) {
        CheckPointVO task = _maidDao.createForUpdate();
        task.setDelegate(updatedContext.getClass().getName());
        task.setContext(SerializerHelper.toSerializedStringOld(updatedContext));
        _maidDao.update(taskId, task);
    }

    @Override
    @DB
    public void popCheckPoint(long taskId) {
        _maidDao.remove(taskId);
    }
    
    protected boolean cleanup(CheckPointVO task) {
        s_logger.info("Cleaning up " + task);
        CleanupMaid delegate = (CleanupMaid)SerializerHelper.fromSerializedString(task.getContext());
        assert delegate.getClass().getName().equals(task.getDelegate()) : "Deserializer says " + delegate.getClass().getName() + " but it's suppose to be " + task.getDelegate();
        
        int result = delegate.cleanup(this);
        if (result <= 0) {
            if (result == 0) {
                s_logger.info("Successfully cleaned up " + task.getId());
            } else {
                s_logger.warn("Unsuccessful in cleaning up " + task + ".  Procedure to cleanup manaully: " + delegate.getCleanupProcedure());
            }
            popCheckPoint(task.getId());
            return true;
        } else {
            s_logger.error("Unable to cleanup " + task.getId());
            return false;
        }
    }
    
    class CleanupTask implements Runnable {
        private Date _curDate;
        public CleanupTask() {
        	_curDate = new Date();
        }

        @Override
        public void run() {
            try {
            	List<CheckPointVO> tasks  = _maidDao.listLeftoversByCutTime(_curDate, _msId);
            	tasks.addAll(_maidDao.listCleanupTasks(_msId));
                
                List<CheckPointVO> retries = new ArrayList<CheckPointVO>();
                
                for (CheckPointVO task : tasks) {
                    try {
                        if (!cleanup(task)) {
                            retries.add(task);
                        }
                    } catch (Exception e) {
                        s_logger.warn("Unable to clean up " + task, e);
                        
                    }
                }
                
                if (retries.size() > 0) {
                    if (_cleanupRetryInterval > 0) {
                        _cleanupScheduler.schedule(this, _cleanupRetryInterval, TimeUnit.SECONDS);
                    } else {
                        for (CheckPointVO task : retries) {
                            s_logger.warn("Cleanup procedure for " + task + ": " + ((CleanupMaid)SerializerHelper.fromSerializedString(task.getContext())).getCleanupProcedure());
                        }
                    }
                }
                
            } catch (Exception e) {
                s_logger.error("Unable to cleanup all of the tasks for " + _msId, e);
            }
        }
    }
}
