/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package eu.dnetlib.espas.sos.client;

import edu.emory.mathcs.backport.java.util.Collections;
import java.net.URL;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 *
 * @author gathanas
 */
public class SOSRequestInfo implements SOSProviderRequestIF{
   private String uniqueRequestId;
   private List<String> observationIDList;
   private List<String> propertyIDList;
   private Map<String, List<TimePeriodConstraint>> observationTimeConstraintMap;
   
   // the following attributes are used ony when the request info object conveys information per provider
   private String providerId;
   private String userId;
   private URL providerEndpoint;
   private Map<String,Map<String, List<String>>> observationOfferingMappings;
   private Map<String,String> observationFoIMappings;
   
   public SOSRequestInfo(String uniqueRequestId, Map<String, List<TimePeriodConstraint>> observationTimeConstraintMap, List<String> propertyIDList) {
      this();
      this.uniqueRequestId = uniqueRequestId;
      this.observationIDList.addAll(observationIDList);
      this.propertyIDList.addAll(observationTimeConstraintMap.keySet());
      this.observationTimeConstraintMap= observationTimeConstraintMap;
   }

   public SOSRequestInfo(String uniqueRequestId, List<String> observationIDList, List<String> propertyIDList, List<TimePeriodConstraint> timeConstraintList) {
      this();
      this.uniqueRequestId = uniqueRequestId;
      this.observationIDList.addAll(observationIDList);
      this.propertyIDList.addAll(propertyIDList);
      for(String obs:observationIDList)
        this.observationTimeConstraintMap.put(obs,timeConstraintList);
   }

   public SOSRequestInfo(List<String> observationIDList, List<String> propertyIDList, List<TimePeriodConstraint> timeConstraintList) {
       this();
      this.observationIDList.addAll(observationIDList);
      this.propertyIDList.addAll(propertyIDList);
      for(String obs:observationIDList)
        this.observationTimeConstraintMap.put(obs,timeConstraintList);
   }

   public SOSRequestInfo() {
       observationIDList = new LinkedList();
       propertyIDList = new LinkedList();
       observationTimeConstraintMap = new HashMap();
   }

   public String getUserId() {
      return userId;
   }

   public void setUserId(String userId) {
      this.userId = userId;
   }

   
   public String getRequestId(){
      return uniqueRequestId;
   }

   public void addObservation(String observationId, List<TimePeriodConstraint> constraints){
       if(this.observationTimeConstraintMap.containsKey(observationId)){
           constraints.addAll(observationTimeConstraintMap.get(observationId));
           this.observationTimeConstraintMap.put(observationId, constraints);
          }
       else
        this.observationTimeConstraintMap.put(observationId, constraints);
       
       this.observationIDList.add(observationId);
   }
   
   @Deprecated
   public List<String> getObservationIDList() {
      return observationIDList;
   }

   public List<String> getPropertyIDList() {
      return propertyIDList;
   }

   @Override
   public List<TimePeriodConstraint> getTimeConstraintList(String observationId) {
        return observationTimeConstraintMap.get(observationId);
   }

   public String getProviderId() {
      return providerId;
   }

   public void setProviderId(String providerId) {
      this.providerId = providerId;
   }

   public URL getProviderEndpoint() {
      return providerEndpoint;
   }

   public void setProviderEndpoint(URL providerEndpoint) {
      this.providerEndpoint = providerEndpoint;
   }

   public void setObservationOfferingMappings(Map<String, Map<String, List<String>>> observationOfferingMappings) {
      this.observationOfferingMappings = observationOfferingMappings;
   }

   public void setObservationFoIMappings(Map<String, String> observationFoIMappings) {
      this.observationFoIMappings = observationFoIMappings;
   }
   
   @Override
   public List<String> getOfferingFor(String observationId, String property) {
      if(this.observationOfferingMappings.containsKey(observationId))
          if(this.observationOfferingMappings.get(observationId).containsKey(property))
            return observationOfferingMappings.get(observationId).get(property);
      return Collections.emptyList();
   }
           
   
   public void setObservationIDList(List<String> observationIDList) {
      this.observationIDList = observationIDList;
   }

   public void setPropertyIDList(List<String> propertyIDList) {
      this.propertyIDList = propertyIDList;
   }

   public void setTimeConstraintList(String obsId, List<TimePeriodConstraint> timeConstraintList) {
      this.observationTimeConstraintMap.put(obsId, timeConstraintList);
   }
   
   public String generateUniqueRequestId(){
      if (uniqueRequestId == null) {
         String key = "@"+(new Date()).getTime()+" # ";
         for (String obId : observationIDList)
            key += obId + ", ";

         key = key.substring(0, key.lastIndexOf(",")) + " # ";

         for (String propId : propertyIDList)
            key += propId + ", ";

         key = key.substring(0, key.lastIndexOf(",")) + " # ";

         for (String obs : observationIDList) {
              for (TimePeriodConstraint tCon : observationTimeConstraintMap.get(obs)) {
                  key += tCon.toString() + ", ";
              }
          }

         key = key.substring(0, key.lastIndexOf(","));

         uniqueRequestId = "SOSReqID-" + key.hashCode();
      }
      return uniqueRequestId;
   }

   @Override
   public String getFeatureOfInterestFor(String observationId) {
      if (observationFoIMappings.containsKey(observationId))
         return this.observationFoIMappings.get(observationId);
      return null;                                                                                                                                                                                                                                                                                                                                                                                                                              
   }

   @Override
   public List<String> getTemporalFilterEncodings(String obsId) {
         List<String> timeConstraintEncodingsList = new LinkedList();
      try {
          
         for(TimePeriodConstraint tConstraint:observationTimeConstraintMap.get(obsId))
            timeConstraintEncodingsList.addAll(tConstraint.getTimeFilterEncodings());
      } catch (ParseException ex) {
         SOSRequestManager._logger.error( null, ex);
      }
      return timeConstraintEncodingsList;
   }

    @Override
    public String getRequestFilterNamespaces() {
//        @todo need to add code for this
        return "xmlns(om,http://www.opengis.net/om/2.0)"; 
    }
   
}


