package com.cloud.network.security;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.management.StandardMBean;

import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.security.LocalSecurityGroupWorkQueue.LocalSecurityGroupWork;
import com.cloud.network.security.SecurityGroupWork.Step;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine.Type;

public class SecurityManagerMBeanImpl extends StandardMBean implements SecurityGroupManagerMBean, RuleUpdateLog {
    SecurityGroupManagerImpl2 _sgMgr;
    boolean _monitoringEnabled = false;
    //keep track of last scheduled, last update sent and last seqno sent per vm. Make it available over JMX
    Map<Long, Date> _scheduleTimestamps = new ConcurrentHashMap<Long, Date>(4000, 100, 64);
    Map<Long, Date> _updateTimestamps = new ConcurrentHashMap<Long, Date>(4000, 100, 64);
    
    
    protected SecurityManagerMBeanImpl(SecurityGroupManagerImpl2 securityGroupManager) {
        super(SecurityGroupManagerMBean.class, false);
        this._sgMgr = securityGroupManager;
    }




    @Override
    public int getQueueSize() {
       return this._sgMgr.getQueueSize();
    }
    
    @Override
    public void logUpdateDetails(Long vmId, Long seqno) {
        if (_monitoringEnabled) {
            _updateTimestamps.put(vmId, new Date());
        }
       
    }
    
    @Override
    public void logScheduledDetails(Set<Long> vmIds) {
        if (_monitoringEnabled) {
            for (Long vmId : vmIds) {
                _scheduleTimestamps.put(vmId, new Date());
            }
        }
    }
    
    @Override
    public void enableUpdateMonitor(boolean enable) {
        _monitoringEnabled = enable;
        if (!enable) {
            _updateTimestamps.clear();
            _scheduleTimestamps.clear();
        }
    }


    @Override
    public Map<Long, Date> getScheduledTimestamps() {
        return _scheduleTimestamps;
    }

    @Override
    public Map<Long, Date> getLastUpdateSentTimestamps() {
        return _updateTimestamps;
    }


    @Override
    public List<Long> getVmsInQueue() {
        return _sgMgr.getWorkQueue().getVmsInQueue();
    }




    @Override
    public void disableSchedulerForVm(Long vmId) {
        _sgMgr.disableSchedulerForVm(vmId,  true);
        
    }

    @Override
    public void enableSchedulerForVm(Long vmId) {
        _sgMgr.disableSchedulerForVm(vmId,  false);
        
    }
    
    @Override
    public Long[] getDisabledVmsForScheduler() {
        return _sgMgr.getDisabledVmsForScheduler();
    }


    @Override
    public void enableSchedulerForAllVms() {
        _sgMgr.enableAllVmsForScheduler();
        
    }


    @Override
    public void scheduleRulesetUpdateForVm(Long vmId) {
        List<Long> affectedVms = new ArrayList<Long>(1);
        affectedVms.add(vmId);
        _sgMgr.scheduleRulesetUpdateToHosts(affectedVms, true, null);
    }


    @Override
    public void tryRulesetUpdateForVmBypassSchedulerVeryDangerous(Long vmId, Long seqno) {
       LocalSecurityGroupWork work = new LocalSecurityGroupWorkQueue.LocalSecurityGroupWork(vmId, seqno, Step.Scheduled);
        _sgMgr.sendRulesetUpdates(work);
    }
    
    @Override
    public void simulateVmStart(Long vmId) {
        //all we need is the vmId
        VMInstanceVO vm = new VMInstanceVO(vmId, 5, "foo", "foo", Type.User, null, HypervisorType.Any, 8, 1, 1, false, false);
        _sgMgr.handleVmStarted(vm);
    }
    
    @Override
    public void disableSchedulerEntirelyVeryDangerous(boolean disable) {
        _sgMgr.disableScheduler(disable);
    }

    @Override
    public boolean isSchedulerDisabledEntirely() {
       return _sgMgr.isSchedulerDisabled();
    }

    @Override
    public void clearSchedulerQueueVeryDangerous() {
        _sgMgr.clearWorkQueue();
    }
}
