/*******************************************************************************
 * Copyright (c), 2001, 2002 N2 Broadband, Inc.  All Rights Reserved.
 *
 * This module contains unpublished, confidential, proprietary
 * material.  The use and dissemination of this material are
 * governed by a license.  The above copyright notice does not
 * evidence any actual or intended publication of this material.
 *
 * Author:  Drake H. Henderson
 * Created:  11-12-01
 *
 ******************************************************************************/

package com.n2bb.sysmonui.alerts;

import com.n2bb.AlertsModule.*;
import com.n2bb.sysmonui.util.SMConstants;
import com.n2bb.util.N2bbException;
import com.n2bb.util.OrbManager;
import com.n2bb.util.ClientTimeoutException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.omg.CORBA.NO_RESPONSE;
import org.omg.CosNaming.NameComponent;

import java.text.Collator;
import java.util.*;

/**
 * Manages communication from UI to Alerts server
 * for CRUD.
 */
public class AlertManager {

  private static Log n2bbLog = LogFactory.getLog(AlertManager.class);

  private static Alert alertFactory = null;

  private static Alert getAlertFactory() throws N2bbException {
    n2bbLog.debug("enter");
    if (alertFactory == null) {
      
      org.omg.CORBA.Object obj = null;
      try {
        NameComponent[] nc = new NameComponent[1];
        nc[0] = new NameComponent(SMConstants.ALERTFACTORY, "");
        obj = OrbManager.getInstance().getRootLevelObject(nc);
      } catch (N2bbException e) {
        n2bbLog.error("failed to get alert factory - message... " + e.getMessage(), e);
        throw e;
      }
      catch (Exception e) {
        n2bbLog.error("failed to get alert factory - message... " + e.getMessage(), e);
        throw new N2bbException("error.corba.findFactory");
      }

      if (obj != null) {
        try {
          alertFactory = AlertHelper.narrow(obj);
        } catch (Exception e) {
          alertFactory = null;
          n2bbLog.error("failed to narrow alert factory - message... " + e.getMessage(), e);
          throw new N2bbException("error.corba.narrowFactory");
        }
      } else
        throw new N2bbException("error.corba.findFactory");

      if (alertFactory == null) {
        n2bbLog.error("alertFactory is null");
        throw new N2bbException("error.corba.factoryNotInitialized");
      }
    }
    return alertFactory;
  }

  /************************
   *
   ************************/
  public static Vector listAlerts() throws N2bbException {
    n2bbLog.debug("enter");
    Vector alertVector = new Vector();
    try {
      AlertData[] alertList = null;
      try {
        alertList = getAlertFactory().listAlerts();
      } catch (N2bbException e) {
        throw e;
      }
      catch (NotFound nf) {
        // no alerts in system
        return alertVector;
      }
      catch (Exception e) {
        n2bbLog.error("failed to list alerts exception - message... " +
                e.getMessage(), e);
        throw new N2bbException("error.genericManager.retrieveList");
      }

      // this block is a temporary solution and to be removed once ISA fix this
      if ((alertList.length == 1) && (alertList[0] == null)) {
        return alertVector;
      }

      for (int j=0; j<alertList.length; j++) {
        if (alertList[j] != null) {
          try {
            alertVector.add(convertDataToBean(alertList[j]));
          } catch (N2bbException e) {
            n2bbLog.error("failed to get an alert exception - message... " + e.getMessage(), e);
            n2bbLog.error("  skipping this alert");
          }
        } else {
          n2bbLog.error("alertData is null at position... " + j);
          n2bbLog.error("  skipping this alert");
          continue;
        }
      }
    }
    catch (N2bbException e) {
      n2bbLog.error("n2bb exception - message... " + e.getMessage(), e);
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
    return alertVector;
  }

  /**
   * Gets map of all alert pattern names to pattern strings.
   */
  public static TreeMap getAlertPatternMap() throws N2bbException {
    n2bbLog.debug("enter");
    Collator collatorApp = Collator.getInstance(Locale.US);
    TreeMap map = new TreeMap(collatorApp);
    try {
      AlertName names[];
      try {
        names = getAlertFactory().getAlertNames();
			} catch (NotFound nf) {
				return map;
      } catch (N2bbException e) {
        throw e;
      }
      catch (Exception e) {
        throw new N2bbException("error.genericManager.retrieveList");
      }

      // this block is a temporary solution and to be removed once ISA fix this
      if ((names.length == 1) && (names[0] == null)) {
        return map;
      }

      for (int j = 0; j < names.length; j++) {
        map.put(names[j].name, names[j].type);
      }

    }
    catch (N2bbException e) {
      n2bbLog.error(e.getMessage(), e);
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
    return map;
  }

  /************************
   *
   ************************/
  public static Vector getAlertPatterns() throws N2bbException {
    n2bbLog.debug("enter");
    Vector namesV = new Vector();
    try {
      AlertName names[];
      try {
        names = getAlertFactory().getAlertNames();
			} catch (NotFound nf) {
				return namesV;
      } catch (N2bbException e) {
        throw e;
      }
      catch (Exception e) {
        n2bbLog.error(
                "failed to list alert patterns exception - message... " +
                e.getMessage(), e);
        throw new N2bbException("error.genericManager.retrieveList");
      }

      // this block is a temporary solution and to be removed once ISA fix this
      if ((names.length == 1) && (names[0] == null)) {
        return namesV;
      }

      for (int j = 0; j < names.length; j++) {
        namesV.add(new AlertPatternBean(names[j].name, names[j].type));
      }

    }
    catch (N2bbException e) {
      n2bbLog.error(e.getMessage(), e);
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
    return namesV;
  }

  public static void saveAlert(AlertDataBean bean) throws N2bbException {
    n2bbLog.debug("enter");
    try {
      AlertData aData = new AlertData();
      if (bean != null) {
        try {
          aData = convertBeanToData(bean);
        } catch (N2bbException e) {
          throw e;
        }
      } else {
        n2bbLog.error("alertBean is null");
        throw new N2bbException("error.alertManager.nullData");
      }

      try {
        getAlertFactory().defineAlertConfiguration(aData);
      } catch (N2bbException e) {
        throw e;
      }
      catch (DuplicateAlert e) {
        n2bbLog.debug(
                "duplicate alert identifier exception - message... " + e.getMessage());
        throw new N2bbException("error.alertManager.dupAlert");
      }
      catch (Exception e) {
        n2bbLog.error("failed to add alert exception - message... " +
                e.getMessage(), e);
        throw new N2bbException("error.genericManager.persistItem");
      }
    } catch (N2bbException e) {
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
  }

  /************************
   *
   ************************/
  public static AlertDataBean getAlert(String alertIdentifier) throws N2bbException {
    n2bbLog.debug("enter");
    AlertDataBean bean = null;
    
    try {
      AlertData aData = new AlertData();
      try {
        aData = getAlertFactory().getAlertDetail(alertIdentifier);
      } catch (N2bbException e) {
        throw e;
      }
      catch (Exception e) {
        n2bbLog.error("getAlertDetail failed exception - message... " +
                e.getMessage(), e);
        throw new N2bbException("error.genericManager.persistedVersion");
      }

      try {
        bean = convertDataToBean(aData);
      } catch (N2bbException e) {
        throw e;
      }
      
    } catch (N2bbException e) {
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
    return bean;
      
  }
  
  /************************
   *
   ************************/
  public static void updateAlert(AlertDataBean bean) throws N2bbException {
    n2bbLog.debug("enter");
    try {
      AlertData aData = new AlertData();
      try {
        aData = getAlertFactory().getAlertDetail(bean.getAlertIdentifier());
      } catch (N2bbException e) {
        throw e;
      }
      catch (Exception e) {
        n2bbLog.error("getAlertDetail failed exception - message... " +
                e.getMessage(), e);
        throw new N2bbException("error.genericManager.persistedVersion");
      }

      if (bean != null) {
        try {
          aData = convertBeanToData(bean);
        } catch (N2bbException e) {
          throw e;
        }
      } else {
        n2bbLog.error("alertBean is null");
        throw new N2bbException("error.alertManager.nullData");
      }

      try {
        getAlertFactory().updateAlertConfiguration(aData);
      } catch (N2bbException e) {
        throw e;
      }
      catch (Exception e) {
        n2bbLog.error("failed to update alert exception - message... " +
                e.getMessage(), e);
        throw new N2bbException("error.genericManager.persistItem");
      }
    } catch (N2bbException e) {
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
  }

  /************************
   *
   ************************/
  public static void deleteAlert(String alertIdentifier) throws N2bbException {
    n2bbLog.debug("enter");
    try {
      try {
        getAlertFactory().deleteAlertConfiguration(alertIdentifier);
      } catch (N2bbException e) {
        throw e;
      }
      catch (Exception e) {
        n2bbLog.error("failed to update alert exception - message... " + e.getMessage(), e);
        throw new N2bbException("error.genericManager.deleteItem");
      }
    } catch (N2bbException e) {
      n2bbLog.error("n2bb exception - message... " + e.getMessage(), e);
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
  }

  /************************
   *
   ************************/
  private static AlertDataBean convertDataToBean(AlertData aData) throws N2bbException {
    n2bbLog.debug("enter");
    AlertDataBean bean = new AlertDataBean();
    try {
      bean.setAlertIdentifier(aData.identifier);
      bean.setAlertPattern((aData.name).name);
      bean.setThresholdCount((aData.threshold).count);
      bean.setThresholdSecs((aData.threshold).seconds);
      bean.setFrequencyCount((aData.frequency).count);
      bean.setFrequencySecs((aData.frequency).seconds);

      String[] actionArray = getAction(aData.action);
      if (actionArray[0] != null) {
        bean.setEmail(actionArray[0]);
      }
      if (actionArray[1] != null) {
        bean.setSNMP(actionArray[1]);
      }

    } catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
    return bean;
  }

  /************************
   *
   ************************/
  private static AlertData convertBeanToData(AlertDataBean bean) throws N2bbException {
    n2bbLog.debug("enter");
    AlertData aData = new AlertData();
    try {
      aData.identifier = bean.getAlertIdentifier();

      AlertName alertName = new AlertName();
      alertName.name = bean.getAlertPattern();
      alertName.type = "";
      aData.name = alertName;

      n2bbLog.debug("Threshold Count... "+ bean.getThresholdCount());
      n2bbLog.debug("Threshold Secs... "+ bean.getThresholdSecs());
      Hertz thresHertz = new Hertz();
      thresHertz.count = bean.getThresholdCount();
      thresHertz.seconds = bean.getThresholdSecs();
      aData.threshold = thresHertz;

      n2bbLog.debug("Frequency Count... "+ bean.getFrequencyCount());
      n2bbLog.debug("Frequency Secs... "+ bean.getFrequencySecs());
      Hertz freqHertz = new Hertz();
      freqHertz.count = bean.getFrequencyCount();
      freqHertz.seconds = bean.getFrequencySecs();
      aData.frequency = freqHertz;

      String email = bean.getEmail();
      String snmp = bean.getSNMP();
      Vector actions = new Vector();

      if (email != null && !email.trim().equals("")) {
        n2bbLog.debug("email... '" + email + "'");
        ActionType actionType = ActionType.from_int(SMConstants.EMAIL);
        Action action = new Action();
        action.type = actionType;
        action.detail = email;
        actions.addElement(action);
      }
      if (snmp != null && !snmp.trim().equals("")) {
        n2bbLog.debug("snmp... '" + snmp + "'");
        ActionType actionType = ActionType.from_int(SMConstants.SNMP);
        Action action = new Action();
        action.type = actionType;
        action.detail = snmp;
        actions.addElement(action);
      }

      n2bbLog.debug("actions vector... " + actions);
      Action[] actionArray = new Action[actions.size()];
      actionArray = (Action[]) actions.toArray(actionArray);
      n2bbLog.debug("actions array... " + actionArray);
      aData.action = actionArray;
      
    } catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
    return aData;
  }

  /************************
   *
   ************************/
  private static String[] getAction(Action[] actions) throws N2bbException {
    String email = null;
    String snmp = null;
    try {
      for (int i=0; i<actions.length; i++) {
        if (actions[i].type.value() == SMConstants.EMAIL)
          email = actions[i].detail;
        else if (actions[i].type.value() == SMConstants.SNMP)
          snmp = actions[i].detail;
      }
      String[] actionArray = {email, snmp};
      return actionArray;

    } catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
  }

  /************************
   *
   ************************/
  public static Vector listAlertHistory(Date start, Date end, 
          String identifier, String alertPattern, String action) throws N2bbException {
    n2bbLog.debug("enter");
    n2bbLog.debug("start... " + start);
    n2bbLog.debug("end... " + end);
    n2bbLog.debug("identifier... " + identifier);
    n2bbLog.debug("alertPattern... " + alertPattern);
    n2bbLog.debug("action... " + action);
    
    if (start == null && end == null && identifier == null && 
        alertPattern == null && action == null)
      return listAlertHistory();
    
    try {
      AlertHistory[] alertList = null;
      
      AlertHistoryFilter ahf = new AlertHistoryFilter();
      
      // start
      if (start == null)
        ahf.start = -1;
      else
        ahf.start = start.getTime();
        
      // end
      if (end == null)
        ahf.end = -1;
      else
        ahf.end = end.getTime();
        
      // identifier
      if (identifier != null)
        ahf.identifier = identifier;
        
      // alertPattern
      if (alertPattern != null)
        ahf.name = alertPattern;

      // action
      if (action != null)
        ahf.action = action;
        
      try {
		    n2bbLog.debug("getting alert history");
        alertList = getAlertFactory().getAlertHistoryWithFilter(ahf);
		    n2bbLog.debug("got alert history");
      } catch (N2bbException e) {
				n2bbLog.error(e.getMessage(), e);
        throw e;
      }
      catch (NotFound nf) {
        // no alerts in system
				n2bbLog.debug("no alert history");
        return new Vector();
      } catch (NO_RESPONSE e) {
        n2bbLog.error(e.getMessage(), e);
        throw new N2bbException("error.corba.timeout");
      }
      catch (org.omg.CORBA.IMP_LIMIT e) {
          if (e.getMessage() != null && e.getMessage().toLowerCase().indexOf("timeout") != -1) {
              throw new ClientTimeoutException();
          }
          else {
              throw new N2bbException("error.genericManager.retrieveList", e);
          }
      }
      catch (Exception e) {
        n2bbLog.error("failed to list history exception - message... " +
                e.getMessage(), e);
        throw new N2bbException("error.genericManager.retrieveList");
      }
      
	    n2bbLog.debug("populating alert history vector");
      return populateHistoryVector(alertList);      
    }
    catch (N2bbException e) {
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
  }
      
  /************************
   *
   ************************/
  public static Vector listAlertHistory() throws N2bbException {
    n2bbLog.debug("enter");
    try {
      AlertHistory[] alertList = null;
      try {
        alertList = getAlertFactory().getAlertHistory();
      } catch (N2bbException e) {
        throw e;
      }
      catch (NotFound nf) {
        // no alerts in system
        return new Vector();
      } catch (NO_RESPONSE e) {
        n2bbLog.error(e.getMessage(), e);
        throw new N2bbException("error.corba.timeout");
      } catch (Exception e) {
        n2bbLog.error("failed to list history exception - message... " +
                e.getMessage(), e);
        throw new N2bbException("error.genericManager.retrieveList");
      }

      return populateHistoryVector(alertList);      
    }
    catch (N2bbException e) {
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
  }

  /************************
   *
   ************************/
  private static Vector populateHistoryVector(AlertHistory[] alertList) throws Exception {
    n2bbLog.debug("enter");
    Vector history = new Vector();
  
    if ((alertList.length == 1) && (alertList[0] == null)) {
      return history;
    }

    for (int j=0; j<alertList.length; j++) {
      if (alertList[j] != null) {
        AlertHistoryBean bean = new AlertHistoryBean();
        bean.setAlertIdentifier(alertList[j].identifier);
        bean.setAlertPattern((alertList[j].name).name);
        bean.setTimeLogged(new Date(alertList[j].timestamp));

        String[] actionArray = getAction(alertList[j].action);
        if (actionArray[0] != null)
          bean.setEmail(actionArray[0]);
        if (actionArray[1] != null)
          bean.setSNMP(actionArray[1]);

        bean.setDescription(alertList[j].detail);
        history.add(bean);
      } else {
        n2bbLog.error("list is null at position... " + j);
        n2bbLog.error("  skipping this alert");
        continue;
      }
    }
    
    return history;
  }
  
  /************************
   * 
   ************************/
  public static TreeSet getAlertHistoryIdentifiers() throws N2bbException {
    Collator collator = Collator.getInstance(Locale.US);
    TreeSet identifiers = new TreeSet(collator);
    try {
      String[] ids = null;
      try {
        ids = getAlertFactory().getAlertHistoryIdentifiers();
      } catch (N2bbException e) {
        throw e;
      }
      catch (NotFound nf) {
        // no identifiers in system
        return identifiers;
      }

      for (int i = 0; i < ids.length; i++) {
        if (ids[i] != null)
          identifiers.add(ids[i]);
      }
    } catch (N2bbException e) {
      n2bbLog.error(e.getMessage(), e);
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
    return identifiers;
  }
  
  /**
   * Gets list of alert patterns for alert history screen.
   */
  public static TreeSet getAlertHistoryPatterns() throws N2bbException {
    Collator collator = Collator.getInstance(Locale.US);
    TreeSet names = new TreeSet(collator);
    try {
      String[] ids = null;
      try {
        ids = getAlertFactory().getAlertHistoryNames();
      } catch (N2bbException e) {
        throw e;
      }
      catch (NotFound nf) {
        // no identifiers in system
        return names;
      }

      for (int i = 0; i < ids.length; i++) {
        if (ids[i] != null)
          names.add(ids[i]);
      }
    } catch (N2bbException e) {
      n2bbLog.error(e.getMessage(), e);
      throw e;
    }
    catch (Exception e) {
      n2bbLog.error(e.getMessage(), e);
      throw new N2bbException("error.other");
    }
    return names;
  }

    /**
     * Saves an alert pattern.
     */
    public static void saveAlertPattern(AlertPatternBean bean) throws N2bbException {
        n2bbLog.debug("enter");
        try {
          try {
            getAlertFactory().defineAlertName(
                    new AlertName(bean.getName(), bean.getPattern())
            );
          } catch (N2bbException e) {
            throw e;
          }
          catch (DuplicateAlertName e) {
            n2bbLog.debug(
                    "duplicate pattern name exception - message... " + e.getMessage());
            throw new N2bbException("error.alertManager.dupAlertPattern");
          }
          catch (Exception e) {
            n2bbLog.error("failed to add alert exception - message... " +
                    e.getMessage(), e);
            throw new N2bbException("error.genericManager.persistItem");
          }
        } catch (N2bbException e) {
          throw e;
        }
        catch (Exception e) {
          n2bbLog.error(e.getMessage(), e);
          throw new N2bbException("error.other");
        }
    }

    /**
     * Gets alert pattern bean.
     */
    public static AlertPatternBean getAlertPattern(String name) throws N2bbException {
        n2bbLog.debug("enter");
        AlertPatternBean bean = null;

        try {
          AlertName aData = new AlertName();
          try {
            aData = getAlertFactory().getAlertName(name);
          } catch (N2bbException e) {
            throw e;
          }
          catch (Exception e) {
            n2bbLog.error("getAlertPattern failed exception - message... " +
                    e.getMessage(), e);
            throw new N2bbException("error.genericManager.persistedVersion");
          }

          bean = new AlertPatternBean(aData.name, aData.type);

        } catch (N2bbException e) {
          throw e;
        }
        catch (Exception e) {
          n2bbLog.error(e.getMessage(), e);
          throw new N2bbException("error.other");
        }
        return bean;

    }

    /**
     * Updates alert pattern
     */
    public static void updateAlertPattern(AlertPatternBean bean) throws N2bbException {
        n2bbLog.debug("enter");
        try {
          AlertName aData = new AlertName();
          try {
            aData = getAlertFactory().getAlertName(bean.getName());
          } catch (N2bbException e) {
            throw e;
          }
          catch (Exception e) {
            n2bbLog.error("getAlertName failed exception - message... " +
                    e.getMessage(), e);
            throw new N2bbException("error.genericManager.persistedVersion");
          }

          if (bean != null) {
              aData = new AlertName(bean.getName(), bean.getPattern());
          } else {
            n2bbLog.error("alertNameBean is null");
            throw new N2bbException("error.alertManager.nullData");
          }

          try {
            getAlertFactory().updateAlertName(aData);
          } catch (N2bbException e) {
            throw e;
          }
          catch (Exception e) {
            n2bbLog.error("failed to update alert pattern exception - message... " +
                    e.getMessage(), e);
            throw new N2bbException("error.genericManager.persistItem");
          }
        } catch (N2bbException e) {
          throw e;
        }
        catch (Exception e) {
          n2bbLog.error(e.getMessage(), e);
          throw new N2bbException("error.other");
        }
    }

    /**
     * Deletes alert patterns.
     */
    public static void deleteAlertPattern(String name) throws N2bbException,
            InUse, NotFound, UnspecifiedException {
        n2bbLog.debug("enter");
        try {
            getAlertFactory().deleteAlertName(name);
        }
        catch (UnspecifiedException e) {
            n2bbLog.error("UnspecifiedException in deleteAlertName", e);
            throw e;
        }
    }
    
    public static void main(String[] a){
    	try
    	{
    		Alert alert = new AlertManager().getAlertFactory();
    		AlertName[] names = alert.getAlertNames();
    		for(int i=0; i<names.length; i++){
    			System.out.println(((AlertName)names[i]).name);
    		}
    	}
    	catch(Exception ex){
    		
    	}
    	
    }

}



