
import java.util.logging.Logger;

import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;




class SodaParser
{
   protected static final Logger LOGGER = Logger.getLogger(ServletCutout.class.getName());

   //public class SodaParamMap extends HashMap<SodaParam, String[]> {};
   Map<SodaParam, String[]> params;


   Pos pos;
   Band band;
   Time time;
   Pol pol;


   public SodaParser(Map<SodaParam, String[]> params)
   {
      LOGGER.info("trace - there are " + params.size() + " params");
      this.params = params;
   }



   /* return null if value not present or the value if present exactly once
    * else throw MultiplicityNotSupoorted SODA_error
    */ 
   private  String soda_getSingleValue(SodaParam name)
   {
      LOGGER.info("trace");

      String[] valArr = params.get(name);

      if(valArr == null)
         return null;
      else
         if(valArr.length == 0)
            return null;
         else if(valArr.length == 1)
         {
            LOGGER.info("ParamFound " + name.toString() + " : " + valArr[0]);
            return valArr[0];
         }
         else
            throw new MultiValuedParamNotSupported(name + " was found " + valArr.length + " times");
   }

/*
   public String sodaReq_getResponseFormat(SodaParamMap params, String defaultResponseFormat)
   {
      String respFormat = soda_getSingleValue(params, "RESPONSEFORMAT");
      return ((respFormat == null) ? defaultResponseFormat : respFormat);
   }
*/

   public  boolean sodaReq_hasSodaId()
   {
      String id = soda_getSingleValue(SodaParam.ID);
      return (id != null);
   }


   public  String sodaReq_getId()
   {
      String pubdid = soda_getSingleValue(SodaParam.ID);
      if(pubdid == null)
         throw new IllegalArgumentException("ID is missing, but is mandatory");
      else
         return pubdid;
   }

  public  Pos  sodaReq_getPosCirclePolygon()
   {
      String valuePos     = soda_getSingleValue(SodaParam.POS);
      String valueCircle  = soda_getSingleValue(SodaParam.CIRCLE);
      String valuePolygon = soda_getSingleValue(SodaParam.POLYGON);

      Pos pos = null;

      if( (valuePos != null) && (valueCircle == null) && (valuePolygon == null) )
      {   
         pos = new Pos(valuePos);
         LOGGER.info(pos.toString());
      }   
      else if( (valuePos == null) && (valueCircle != null) && (valuePolygon == null) )
      {   
         Circle circle = new Circle(valueCircle);
         LOGGER.info(circle.toString());
         pos = new Pos(circle);
      }   
      else if( (valuePos == null) && (valueCircle == null) && (valuePolygon != null) )
      {
         Polygon polygon = new Polygon(valuePolygon);
         LOGGER.info(polygon.toString());
         pos = new Pos(polygon);
      }
      else
      {
         throw new IllegalArgumentException("Exactly one of POS | CIRCLE | POLYGON must be given.");
      }

      return pos;
   }


   public  Band sodaReq_getBand()
   {
      String value = soda_getSingleValue(SodaParam.BAND);
      if(value == null)
         return null;
      else
         return new Band(value);
   }


   public  Time sodaReq_getTime()
   {
      String value = soda_getSingleValue(SodaParam.TIME);
      if(value == null)
         return null;
      else
         return new Time(value);
   }

  public  Pol sodaReq_getPol()
   {
      String[] valArr = params.get(SodaParam.POL);


      if(valArr == null)
         return null;
      else if(valArr.length < 1)
         return null;
      else
      {
         LOGGER.info("ParamFound " + SodaParam.POL.toString() + " : " + Arrays.toString(valArr));
         return new Pol(valArr);
      }
   }


  /* VLKB */


  public  String vlkbReq_getPubdid()
  {
     String pubdid = soda_getSingleValue(SodaParam.pubdid);
     if(pubdid == null)
        throw new IllegalArgumentException(SodaParam.pubdid.toString() + " is missing, but is mandatory");
     else
        return pubdid;
  }

  public  Pos vlkbReq_getCircleRect()
  {
     Pos pos = null;

     String l_value = soda_getSingleValue(SodaParam.l);
     String b_value = soda_getSingleValue(SodaParam.b);

     if( (l_value != null) && (b_value != null ) )
     {
        String r_value = soda_getSingleValue(SodaParam.r);
        if(r_value != null)
        {
           Circle circle = new Circle(l_value + " " + b_value + " " + r_value);
           pos = new Pos(circle);
        }
        else
        {
           String dl_value = soda_getSingleValue(SodaParam.dl);
           String db_value = soda_getSingleValue(SodaParam.db);
           if((dl_value != null) && (db_value != null))
           {
              double l  = Double.parseDouble(l_value);
              double b  = Double.parseDouble(b_value);
              double dl = Double.parseDouble(dl_value);
              double db = Double.parseDouble(db_value);

              Range range = new Range(l, b, dl, db);
              pos = new Pos(range);
           }
           else
           {
              throw new IllegalArgumentException("one of 'r' or '(dl,db)' pair must be provided to designate sky area");
           }
        }
     }
     else
     {
        throw new IllegalArgumentException("VLKB sky position center (l,b) is missing however is mandatory");
     }

     return pos;
  }


  public  Band vlkbReq_getVelocity()
  {
     Band band = null;

     String cvlow = soda_getSingleValue(SodaParam.vl);
     String cvup  = soda_getSingleValue(SodaParam.vu);
     //String cvtype = soda_getSingleValue(params, "vtype"); // "1"=VELO_LSRK or "2"=WAVE_Barycentirc

     boolean vel_valid = (cvlow != null) && (cvup != null);

     if(vel_valid)
     {
        double vel_low = Double.parseDouble(cvlow);
        double vel_up  = Double.parseDouble(cvup);
        band = new Band(vel_low, vel_up);
     }

     return band;
  }

  public  boolean vlkbReq_getNullValues()
  {
     return (null != soda_getSingleValue(SodaParam.nullvals));
  }

}

