/**
 * 
 */
package org.exoplatform.social.service.malwareDetection;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.social.service.malwareDetection.connector.MalwareDetectionConnector;
import org.exoplatform.social.service.malwareDetection.connector.MalwareDetectionItemConnector;

/**
 * Is extended by all MalwareDetectionItemConnector and MalwareDetectionConnector connectors, and allows to build configuration needed by a list of connectors that is used for Malware detection.
 * 
 */
public class MalwareDetectionService {
  
  private Map<String, MalwareDetectionItemConnector> malwareDetectionItemConnectors = new HashMap<String, MalwareDetectionItemConnector>();
  private Map<String, MalwareDetectionConnector> malwareDetectionConnectors = new HashMap<String, MalwareDetectionConnector>();
  private static final Log LOGGER = ExoLogger.getExoLogger(MalwareDetectionService.class);
  
  
  /**
   * Add Malware detection item connector to the service
   * @param malwareDetectionItemConnector the Malware detection item connector to add
   * @LevelAPI Experimental
   */
  public void addMalwareDetectionItemConnector(MalwareDetectionItemConnector malwareDetectionItemConnector) {
    addMalwareDetectionItemConnector(malwareDetectionItemConnector, false);
  }
  
  /**
   * Add Malware detection connector to the service
   * @param malwareDetectionConnector the Malware detection connector to add
   * @LevelAPI Experimental
   */
  public void addMalwareDetectionConnector(MalwareDetectionConnector malwareDetectionConnector) {
    addMalwareDetectionConnector(malwareDetectionConnector, false);
  }
  
  /**
   * Add malware detection item connector to the service
   * @param malwareDetectionItemConnector the malware detection item connector to add
   * @param override equal true if we can override an existing connector, false otherwise
   * @LevelAPI Experimental
   */
  public void addMalwareDetectionItemConnector(MalwareDetectionItemConnector malwareDetectionItemConnector, Boolean override) {
    if (malwareDetectionItemConnectors.containsKey(malwareDetectionItemConnector.getType()) && override.equals(false)) {
      LOGGER.error("Impossible to add malware detection item connector {}. A malware detection item with the same type has already been registered.", malwareDetectionItemConnector.getType());
    } else {
      malwareDetectionItemConnectors.put(malwareDetectionItemConnector.getType(), malwareDetectionItemConnector);
      LOGGER.info("A Malware detection item connector has been added: {}", malwareDetectionItemConnector.getType());
    }
  }
  
  /**
   * Add malware detection connector to the service
   * @param malwareDetectionConnector the malware detection connector to add
   * @param override equal true if we can override an existing connector, false otherwise
   * @LevelAPI Experimental
   */
  public void addMalwareDetectionConnector(MalwareDetectionConnector malwareDetectionConnector, Boolean override) {
    if (malwareDetectionConnectors.containsKey(malwareDetectionConnector.getType()) && override.equals(false)) {
      LOGGER.error("Impossible to add malware detection connector {}. A malware detection item with the same type has already been registered.", malwareDetectionConnector.getType());
    } else {
      malwareDetectionConnectors.put(malwareDetectionConnector.getType(), malwareDetectionConnector);
      LOGGER.info("A Malware detection connector has been added: {}", malwareDetectionConnector.getType());
    }
  }
  
  /**
   * Gets all current malware detection item connectors
   * @return Malware detection item connectors
   * @LevelAPI Experimental
   */
  public Map<String, MalwareDetectionItemConnector> getMalwareDetectionItemConnectors() {
    return malwareDetectionItemConnectors;
  }
  
  /**
   * Gets all current malware detection connectors
   * @return Malware detection connectors
   * @LevelAPI Experimental
   */
  public Map<String, MalwareDetectionConnector> getMalwareDetectionConnectors() {
    return malwareDetectionConnectors;
  }
  
  /**
   * Gets default malware detection connector
   * @return Default malware detection connector
   * @LevelAPI Experimental
   */
  public MalwareDetectionConnector getDefaultMalwareDetectionConnector() {
    for (Map.Entry malwareDetectionConnectorEntry : malwareDetectionConnectors.entrySet()) {
      MalwareDetectionConnector malwareDetectionConnector = (MalwareDetectionConnector) malwareDetectionConnectorEntry.getValue();
      if (malwareDetectionConnector.isDefault()){
        return malwareDetectionConnector;
      }
    }
    return null;
  }
  
  public void checkAndProcessNewInfectedItems() {
    MalwareDetectionConnector defaultMalwareDetectionConnector = getDefaultMalwareDetectionConnector();
    if (defaultMalwareDetectionConnector != null) {
      List<String> newInfectedItemsPaths = defaultMalwareDetectionConnector.getInfectedItemsPaths();
      for (String newInfectedItemPath : newInfectedItemsPaths) {
        processInfectedItem(newInfectedItemPath);
      }
    }
  }
  
  public void processInfectedItem(String infectedItemPath) {
    for (Map.Entry malwareDetectionItemConnectorEntry : malwareDetectionItemConnectors.entrySet()) {
      MalwareDetectionItemConnector malwareDetectionItemConnector = (MalwareDetectionItemConnector) malwareDetectionItemConnectorEntry.getValue();
      if (malwareDetectionItemConnector.canProcessInfectedItem(infectedItemPath)) {
        malwareDetectionItemConnector.processInfectedItem(infectedItemPath);
      }
    }
  }
}