/**
 *  Copyright (C) 2010 Cloud.com, Inc.  All rights reserved.
 * 
 * This software is licensed under the GNU General Public License v3 or later.
 * 
 * It is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package com.cloud.alert;

import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import javax.ejb.Local;
import javax.mail.Authenticator;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.naming.ConfigurationException;

import org.apache.log4j.Logger;

import com.cloud.alert.dao.AlertDao;
import com.cloud.capacity.CapacityVO;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterIpAddressDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePoolVO;
import com.cloud.storage.dao.StoragePoolDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.vm.dao.ConsoleProxyDao;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.SecondaryStorageVmDao;
import com.cloud.vm.dao.UserVmDao;
import com.sun.mail.smtp.SMTPMessage;
import com.sun.mail.smtp.SMTPSSLTransport;
import com.sun.mail.smtp.SMTPTransport;

@Local(value={AlertManager.class})
public class AlertManagerImpl implements AlertManager {
    private static final Logger s_logger = Logger.getLogger(AlertManagerImpl.class.getName());

    private static final long INITIAL_DELAY = 5L * 60L * 1000L; // five minutes expressed in milliseconds

    private static final DecimalFormat _dfPct = new DecimalFormat("###.##");
    private static final DecimalFormat _dfWhole = new DecimalFormat("########");

    private String _name = null;
    private EmailAlert _emailAlert;
    @Inject private AlertDao _alertDao;
    @Inject private HostDao _hostDao;
    @Inject protected StorageManager _storageMgr;
    @Inject private ServiceOfferingDao _offeringsDao;
    @Inject private CapacityDao _capacityDao;
    @Inject private DomainRouterDao _routerDao;
    @Inject private ConsoleProxyDao _consoleProxyDao;
    @Inject private SecondaryStorageVmDao _secStorgaeVmDao;
    @Inject private UserVmDao _userVmDao;
    @Inject private DataCenterDao _dcDao;
    @Inject private HostPodDao _podDao;
    @Inject private VolumeDao _volumeDao;
    @Inject private IPAddressDao _publicIPAddressDao;
    @Inject private DataCenterIpAddressDao _privateIPAddressDao;
    @Inject private StoragePoolDao _storagePoolDao;
    
    private Timer _timer = null;
    private float _cpuOverProvisioningFactor = 1;
    private long _capacityCheckPeriod = 60L * 60L * 1000L; // one hour by default
    private double _memoryCapacityThreshold = 0.75;
    private double _cpuCapacityThreshold = 0.75;
    private double _storageCapacityThreshold = 0.75;
    private double _storageAllocCapacityThreshold = 0.75;
    private double _publicIPCapacityThreshold = 0.75;
    private double _privateIPCapacityThreshold = 0.75;

    @Override
    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
        _name = name;

        ComponentLocator locator = ComponentLocator.getCurrentLocator();
        ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
        if (configDao == null) {
            s_logger.error("Unable to get the configuration dao.");
            return false;
        }

        Map<String, String> configs = configDao.getConfiguration("management-server", params);

        // set up the email system for alerts
        String emailAddressList = configs.get("alert.email.addresses");
        String[] emailAddresses = null;
        if (emailAddressList != null) {
            emailAddresses = emailAddressList.split(",");
        }

        String smtpHost = configs.get("alert.smtp.host");
        int smtpPort = NumbersUtil.parseInt(configs.get("alert.smtp.port"), 25);
        String useAuthStr = configs.get("alert.smtp.useAuth");
        boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr));
        String smtpUsername = configs.get("alert.smtp.username");
        String smtpPassword = configs.get("alert.smtp.password");
        String emailSender = configs.get("alert.email.sender");
        String smtpDebugStr = configs.get("alert.smtp.debug");
        boolean smtpDebug = false;
        if (smtpDebugStr != null) {
            smtpDebug = Boolean.parseBoolean(smtpDebugStr);
        }

        _emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug);

        String storageCapacityThreshold = configs.get("storage.capacity.threshold");
        String cpuCapacityThreshold = configs.get("cpu.capacity.threshold");
        String memoryCapacityThreshold = configs.get("memory.capacity.threshold");
        String storageAllocCapacityThreshold = configs.get("storage.allocated.capacity.threshold");
        String publicIPCapacityThreshold = configs.get("public.ip.capacity.threshold");
        String privateIPCapacityThreshold = configs.get("private.ip.capacity.threshold");
        
        if (storageCapacityThreshold != null) {
            _storageCapacityThreshold = Double.parseDouble(storageCapacityThreshold);
        }
        if (storageAllocCapacityThreshold != null) {
            _storageAllocCapacityThreshold = Double.parseDouble(storageAllocCapacityThreshold);
        }
        if (cpuCapacityThreshold != null) {
            _cpuCapacityThreshold = Double.parseDouble(cpuCapacityThreshold);
        }
        if (memoryCapacityThreshold != null) {
            _memoryCapacityThreshold = Double.parseDouble(memoryCapacityThreshold);
        }
        if (publicIPCapacityThreshold != null) {
        	_publicIPCapacityThreshold = Double.parseDouble(publicIPCapacityThreshold);
        }
        if (privateIPCapacityThreshold != null) {
        	_privateIPCapacityThreshold = Double.parseDouble(privateIPCapacityThreshold);
        }

        String capacityCheckPeriodStr = configs.get("capacity.check.period");
        if (capacityCheckPeriodStr != null) {
            _capacityCheckPeriod = Long.parseLong(capacityCheckPeriodStr);
            if(_capacityCheckPeriod <= 0)
            	_capacityCheckPeriod = Long.parseLong(Config.CapacityCheckPeriod.getDefaultValue());
        }
        
        String cpuOverProvisioningFactorStr = configs.get("cpu.overprovisioning.factor");
        if (cpuOverProvisioningFactorStr != null) {
            _cpuOverProvisioningFactor = NumbersUtil.parseFloat(cpuOverProvisioningFactorStr,1);
            if(_cpuOverProvisioningFactor < 1){
            	_cpuOverProvisioningFactor = 1;
            }
        }

        _timer = new Timer("CapacityChecker");

        return true;
    }

    @Override
    public String getName() {
        return _name;
    }

    @Override
    public boolean start() {
        _timer.schedule(new CapacityChecker(), INITIAL_DELAY, _capacityCheckPeriod);
        return true;
    }

    @Override
    public boolean stop() {
        _timer.cancel();
        return true;
    }

    @Override
    public void clearAlert(short alertType, long dataCenterId, long podId) {
        try {
            if (_emailAlert != null) {
                _emailAlert.clearAlert(alertType, dataCenterId, podId);
            }
        } catch (Exception ex) {
            s_logger.error("Problem clearing email alert", ex);
        }
    }

    @Override
    public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String body) {
        // TODO:  queue up these messages and send them as one set of issues once a certain number of issues is reached?  If that's the case,
        //         shouldn't we have a type/severity as part of the API so that severe errors get sent right away?
        try {
            if (_emailAlert != null) {
                _emailAlert.sendAlert(alertType, dataCenterId, podId, subject, body);
            }
        } catch (Exception ex) {
            s_logger.error("Problem sending email alert", ex);
        }
    }

    @Override @DB
    public void recalculateCapacity() {
        // FIXME: the right way to do this is to register a listener (see RouterStatsListener, VMSyncListener)
        //        for the vm sync state.  The listener model has connects/disconnects to keep things in sync much better
        //        than this model right now, so when a VM is started, we update the amount allocated, and when a VM
        //        is stopped we updated the amount allocated, and when VM sync reports a changed state, we update
        //        the amount allocated.  Hopefully it's limited to 3 entry points and will keep the amount allocated
        //        per host accurate.

        if (s_logger.isTraceEnabled()) {
            s_logger.trace("recalculating system capacity");
        }
        List<CapacityVO> newCapacities = new ArrayList<CapacityVO>();

        // get all hosts..
        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
        sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
        List<HostVO> hosts = _hostDao.search(sc, null);

        // prep the service offerings
        List<ServiceOfferingVO> offerings = _offeringsDao.listAllIncludingRemoved();
        Map<Long, ServiceOfferingVO> offeringsMap = new HashMap<Long, ServiceOfferingVO>();
        for (ServiceOfferingVO offering : offerings) {
            offeringsMap.put(offering.getId(), offering);
        }
        
        // Calculate storage pool capacity
        List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
        for (StoragePoolVO pool : storagePools) {
            long disk = 0l;
            Pair<Long, Long> sizes = _volumeDao.getCountAndTotalByPool(pool.getId());
            disk = sizes.second();
            _storageMgr.createCapacityEntry(pool, disk);
        }

        // Calculate new Public IP capacity
        List<DataCenterVO> datacenters = _dcDao.listAllIncludingRemoved();
        for (DataCenterVO datacenter : datacenters) {
            long dcId = datacenter.getId();

            //NOTE
            //What happens if we have multiple vlans? Dashboard currently shows stats 
            //with no filter based on a vlan
            //ideal way would be to remove out the vlan param, and filter only on dcId
            //implementing the same
            int totalPublicIPs = _publicIPAddressDao.countIPsForDashboard(dcId, false);
            int allocatedPublicIPs = _publicIPAddressDao.countIPsForDashboard(dcId, true);

            CapacityVO newPublicIPCapacity = new CapacityVO(null, dcId, null, allocatedPublicIPs, totalPublicIPs, CapacityVO.CAPACITY_TYPE_PUBLIC_IP);
            newCapacities.add(newPublicIPCapacity);
        }

        // Calculate new Private IP capacity
        List<HostPodVO> pods = _podDao.listAllIncludingRemoved();
        for (HostPodVO pod : pods) {
            long podId = pod.getId();
            long dcId = pod.getDataCenterId();

            int totalPrivateIPs = _privateIPAddressDao.countIPs(podId, dcId, false);
            int allocatedPrivateIPs = _privateIPAddressDao.countIPs(podId, dcId, true);

            CapacityVO newPrivateIPCapacity = new CapacityVO(null, dcId, podId, allocatedPrivateIPs, totalPrivateIPs, CapacityVO.CAPACITY_TYPE_PRIVATE_IP);
            newCapacities.add(newPrivateIPCapacity);
        }

        Transaction txn = Transaction.currentTxn();
        try {
        	txn.start();

        	_capacityDao.clearNonStorageCapacities2();
        	
            for (CapacityVO newCapacity : newCapacities) {
            	s_logger.trace("Executing capacity update");
                _capacityDao.persist(newCapacity);
                s_logger.trace("Done with capacity update");
            }
            txn.commit();
        } catch (Exception ex) {
        	txn.rollback();
        	s_logger.error("Unable to start transaction for capacity update");
        }finally {
        	txn.close();
        }
    }

    class CapacityChecker extends TimerTask {
        @Override
		public void run() {
            recalculateCapacity();

            // abort if we can't possibly send an alert...
            if (_emailAlert == null) {
                return;
            }

            try {
                List<CapacityVO> capacityList = _capacityDao.listAllIncludingRemoved();
                Map<String, List<CapacityVO>> capacityDcTypeMap = new HashMap<String, List<CapacityVO>>();

                for (CapacityVO capacity : capacityList) {
                    long dataCenterId = capacity.getDataCenterId();
                    Long podId = capacity.getPodId();
                    short type = capacity.getCapacityType();
                    String key = null;
                    if((type == CapacityVO.CAPACITY_TYPE_PUBLIC_IP) || (type == CapacityVO.CAPACITY_TYPE_SECONDARY_STORAGE)){
                        key = "dc" + dataCenterId + "t" + type;    
                    } else {
                        key = "pod" + podId + "t" + type;
                    }
                    
                    List<CapacityVO> list = capacityDcTypeMap.get(key);
                    if (list == null) {
                        list = new ArrayList<CapacityVO>();
                    }
                    list.add(capacity);
                    capacityDcTypeMap.put(key, list);
                }

                for (String keyValue : capacityDcTypeMap.keySet()) {
                    List<CapacityVO> capacities = capacityDcTypeMap.get(keyValue);
                    double totalCapacity = 0d;
                    double usedCapacity = 0d;
                    CapacityVO cap = capacities.get(0);
                    short capacityType = cap.getCapacityType();
                    long dataCenterId = cap.getDataCenterId();
                    Long podId = cap.getPodId();

                    for (CapacityVO capacity : capacities) {
                        totalCapacity += capacity.getTotalCapacity();
                        usedCapacity += capacity.getUsedCapacity();
                    }

                    double capacityPct = (usedCapacity / totalCapacity);
                    double thresholdLimit = 1.0;
                    DataCenterVO dcVO = _dcDao.findById(dataCenterId);
                    String dcName = ((dcVO == null) ? "unknown" : dcVO.getName());
                    String podName = "";
                    if( podId != null){
                        HostPodVO pod = _podDao.findById(podId);
                        podName = ((pod == null) ? "unknown" : pod.getName());
                    }
                    String msgSubject = "";
                    String msgContent = "";
                    String totalStr = "";
                    String usedStr = "";
                    String pctStr = formatPercent(capacityPct);

                    // check for over threshold
                    switch (capacityType) {
                    case CapacityVO.CAPACITY_TYPE_MEMORY:
                        thresholdLimit = _memoryCapacityThreshold;
                        msgSubject = "System Alert: Low Available Memory in pod "+podName+" of availablity zone " + dcName;
                        totalStr = formatBytesToMegabytes(totalCapacity);
                        usedStr = formatBytesToMegabytes(usedCapacity);
                        msgContent = "System memory is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)";
                        break;
                    case CapacityVO.CAPACITY_TYPE_CPU:
                        thresholdLimit = _cpuCapacityThreshold;
                        msgSubject = "System Alert: Low Unallocated CPU in pod "+podName+" of availablity zone " + dcName;
                        totalStr = _dfWhole.format(totalCapacity);
                        usedStr = _dfWhole.format(usedCapacity);
                        msgContent = "Unallocated CPU is low, total: " + totalStr + " Mhz, used: " + usedStr + " Mhz (" + pctStr + "%)";
                        break;
                    case CapacityVO.CAPACITY_TYPE_STORAGE:
                        thresholdLimit = _storageCapacityThreshold;
                        msgSubject = "System Alert: Low Available Storage in pod "+podName+" of availablity zone " + dcName;
                        totalStr = formatBytesToMegabytes(totalCapacity);
                        usedStr = formatBytesToMegabytes(usedCapacity);
                        msgContent = "Available storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)";
                        break;
                    case CapacityVO.CAPACITY_TYPE_STORAGE_ALLOCATED:
                        thresholdLimit = _storageAllocCapacityThreshold;
                        msgSubject = "System Alert: Remaining unallocated Storage is low in pod "+podName+" of availablity zone " + dcName;
                        totalStr = formatBytesToMegabytes(totalCapacity);
                        usedStr = formatBytesToMegabytes(usedCapacity);
                        msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)";
                        break;
                    case CapacityVO.CAPACITY_TYPE_PUBLIC_IP:
                        thresholdLimit = _publicIPCapacityThreshold;
                        msgSubject = "System Alert: Number of unallocated public IPs is low in availablity zone " + dcName;
                        totalStr = Double.toString(totalCapacity);
                        usedStr = Double.toString(usedCapacity);
                        msgContent = "Number of unallocated public IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
                        break;
                    case CapacityVO.CAPACITY_TYPE_PRIVATE_IP:
                    	thresholdLimit = _privateIPCapacityThreshold;
                    	msgSubject = "System Alert: Number of unallocated private IPs is low in pod "+podName+" of availablity zone " + dcName;
                    	totalStr = Double.toString(totalCapacity);
                        usedStr = Double.toString(usedCapacity);
                    	msgContent = "Number of unallocated private IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
                    	break;
                    }

                    if (capacityPct > thresholdLimit) {
                        _emailAlert.sendAlert(capacityType, dataCenterId, null, msgSubject, msgContent);
                    } else {
                        _emailAlert.clearAlert(capacityType, dataCenterId, null);
                    }
                }
            } catch (Exception ex) {
                s_logger.error("Exception in CapacityChecker", ex);
            }
        }
    }

    class EmailAlert {
        private Session _smtpSession;
        private InternetAddress[] _recipientList;
        private final String _smtpHost;
        private int _smtpPort = -1;
        private boolean _smtpUseAuth = false;
        private final String _smtpUsername;
        private final String _smtpPassword;
        private final String _emailSender;

        public EmailAlert(String[] recipientList, String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword, String emailSender, boolean smtpDebug) {
            if (recipientList != null) {
                _recipientList = new InternetAddress[recipientList.length];
                for (int i = 0; i < recipientList.length; i++) {
                    try {
                        _recipientList[i] = new InternetAddress(recipientList[i], recipientList[i]);
                    } catch (Exception ex) {
                        s_logger.error("Exception creating address for: " + recipientList[i], ex);
                    }
                }
            }

            _smtpHost = smtpHost;
            _smtpPort = smtpPort;
            _smtpUseAuth = smtpUseAuth;
            _smtpUsername = smtpUsername;
            _smtpPassword = smtpPassword;
            _emailSender = emailSender;

            if (_smtpHost != null) {
                Properties smtpProps = new Properties();
                smtpProps.put("mail.smtp.host", smtpHost);
                smtpProps.put("mail.smtp.port", smtpPort);
                smtpProps.put("mail.smtp.auth", ""+smtpUseAuth);
                if (smtpUsername != null) {
                    smtpProps.put("mail.smtp.user", smtpUsername);
                }

                smtpProps.put("mail.smtps.host", smtpHost);
                smtpProps.put("mail.smtps.port", smtpPort);
                smtpProps.put("mail.smtps.auth", ""+smtpUseAuth);
                if (smtpUsername != null) {
                    smtpProps.put("mail.smtps.user", smtpUsername);
                }

                if ((smtpUsername != null) && (smtpPassword != null)) {
                    _smtpSession = Session.getInstance(smtpProps, new Authenticator() {
                        @Override
                        protected PasswordAuthentication getPasswordAuthentication() {
                            return new PasswordAuthentication(smtpUsername, smtpPassword);
                        }
                    });
                } else {
                    _smtpSession = Session.getInstance(smtpProps);
                }
                _smtpSession.setDebug(smtpDebug);
            } else {
                _smtpSession = null;
            }
        }

        // TODO:  make sure this handles SSL transport (useAuth is true) and regular
        public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String content) throws MessagingException, UnsupportedEncodingException {
            AlertVO alert = null;
            if ((alertType != AlertManager.ALERT_TYPE_HOST) &&
                (alertType != AlertManager.ALERT_TYPE_USERVM) &&
                (alertType != AlertManager.ALERT_TYPE_DOMAIN_ROUTER) &&
                (alertType != AlertManager.ALERT_TYPE_CONSOLE_PROXY) &&
                (alertType != AlertManager.ALERT_TYPE_STORAGE_MISC) &&
                (alertType != AlertManager.ALERT_TYPE_MANAGMENT_NODE)) {
                alert = _alertDao.getLastAlert(alertType, dataCenterId, podId);
            }

            if (alert == null) {
                // set up a new alert
                AlertVO newAlert = new AlertVO();
                newAlert.setType(alertType);
                newAlert.setSubject(subject);
                newAlert.setPodId(podId);
                newAlert.setDataCenterId(dataCenterId);
                newAlert.setSentCount(1); // initialize sent count to 1 since we are now sending an alert
                newAlert.setLastSent(new Date());
                _alertDao.persist(newAlert);
            } else {
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Have already sent: " + alert.getSentCount() + " emails for alert type '" + alertType + "' -- skipping send email");
                }
                return;
            }

            if (_smtpSession != null) {
                SMTPMessage msg = new SMTPMessage(_smtpSession);
                msg.setSender(new InternetAddress(_emailSender, _emailSender));
                msg.setFrom(new InternetAddress(_emailSender, _emailSender));
                for (InternetAddress address : _recipientList) {
                    msg.addRecipient(RecipientType.TO, address);
                }
                msg.setSubject(subject);
                msg.setSentDate(new Date());
                msg.setContent(content, "text/plain");
                msg.saveChanges();

                SMTPTransport smtpTrans = null;
                if (_smtpUseAuth) {
                    smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
                } else {
                    smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
                }
                smtpTrans.connect();
                smtpTrans.sendMessage(msg, msg.getAllRecipients());
                smtpTrans.close();
            }
        }

        public void clearAlert(short alertType, long dataCenterId, Long podId) {
            if (alertType != -1) {
                AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId);
                if (alert != null) {
                    AlertVO updatedAlert = _alertDao.createForUpdate();
                    updatedAlert.setResolved(new Date());
                    _alertDao.update(alert.getId(), updatedAlert);
                }
            }
        }
    }

    private static String formatPercent(double percentage) {
        return _dfPct.format(percentage*100);
    }

    private static String formatBytesToMegabytes(double bytes) {
        double megaBytes = (bytes / (1024 * 1024));
        return _dfWhole.format(megaBytes);
    }
}
