package kz.cafe.client.rest;

import java.text.*;
import java.util.*;
import javax.servlet.http.*;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import org.apache.commons.logging.*;
import kz.cafe.client.*;
import kz.cafe.client.rest.wrappers.*;
import kz.cafe.constants.*;
import kz.cafe.db.*;
import kz.cafe.db.model.*;
import kz.cafe.db.service.*;
import kz.cafe.exceptions.*;
import kz.cafe.utils.*;



@Path("/cafe")
public class FECafe extends FEAbstractService{
   private static Log log = LogFactory.getLog(FECafe.class);

   private static final String LOG = "[JR CAFE] ";





   // private UserSession4 session = null;

   public FECafe(@Context HttpServletRequest hsr){
      super(ServiceRequestModel.buildUpponServlet(hsr), LOG);
   }





   @SuppressWarnings("unchecked")
   @GET
   @Path("/list/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRCafeListResponse list(@PathParam("LANG") String sLang,
                                  @PathParam("TIME") long lTime){

      JRCafeListResponse response = new JRCafeListResponse();

      try{
         InterfaceConstants.LANGS lang = validateLang(sLang);

         for(MCafe mCafe : (List<MCafe>) MongoService.getListFrontEnd(MCafe.class, lTime)){

            if(response.checkDeleted(mCafe)){
               JRCafeListResponse.JMItem item = response.add();

               item.fillIn(lang, mCafe);
               try{
                  item.type = mCafe.types.iterator().next();
               }
               catch (Exception e){
                  item.type = 0;
               }
               item.rate = mCafe.rate;
               item.price = mCafe.price;
               
               
               //With no GMT
               item.timeClose = mCafe.timeCloseMo;
               item.timeOpen = mCafe.timeOpenMo;
               item.timeCloseWeekend = mCafe.timeCloseSa;
               item.timeOpenWeekend = mCafe.timeOpenSa;
               
               
               
               item.phone = mCafe.phone;
               item.address = mCafe.address.get(lang);

               if(mCafe.service == null || mCafe.service.size() == 0){
                  item.service = "";
               }
               else{
                  String sService = mCafe.service.toString();
                  item.service = sService.substring(1, sService.length() - 1);
               }

               item.coordinates = mCafe.coordinates;

               item.hasDelivery = mCafe.hasDelivery;
               item.hasReservation = mCafe.hasReservation;

               if(mCafe.types == null || mCafe.types.size() == 0){
                  item.types = "";
               }
               else{
                  String sTypes = mCafe.types.toString();
                  item.types = sTypes.substring(1, sTypes.length() - 1);
               }

               if(mCafe.cuisines == null || mCafe.cuisines.size() == 0){
                  item.cuisines = "";
               }
               else{
                  String sCuisines = mCafe.cuisines.toString();
                  item.cuisines = sCuisines.substring(1, sCuisines.length() - 1);
               }

               if(mCafe.faceControl == null || mCafe.faceControl.size() == 0){
                  item.requirements = "";
               }
               else{
                  String sFaceControl = mCafe.faceControl.toString();
                  item.requirements = sFaceControl.substring(1, sFaceControl.length() - 1);
               }

               item.tables_total = mCafe.tableTotal;
               item.tables_free  = mCafe.tableFree;
               
               item.bill_average_min = mCafe.bill_average_min;
               item.bill_average_max = mCafe.bill_average_max;
               
               item.city = mCafe.city;
               

               //With no GMT
               item.timeCloseMo = mCafe.timeCloseMo;
               item.timeOpenMo = mCafe.timeOpenMo;
               item.timeCloseTu = mCafe.timeCloseTu;
               item.timeOpenTu = mCafe.timeOpenTu;
               item.timeCloseWe = mCafe.timeCloseWe;
               item.timeOpenWe = mCafe.timeOpenWe;
               item.timeCloseTh = mCafe.timeCloseTh;
               item.timeOpenTh = mCafe.timeOpenTh;
               item.timeCloseFr = mCafe.timeCloseFr;
               item.timeOpenFr = mCafe.timeOpenFr;
               item.timeCloseSa = mCafe.timeCloseSa;
               item.timeOpenSa = mCafe.timeOpenSa;
               item.timeCloseSu = mCafe.timeCloseSu;
               item.timeOpenSu = mCafe.timeOpenSu;
               

               
               item.timeOrdersFrom      = mCafe.timeOrdersFrom;
               item.timeOrdersTo        = mCafe.timeOrdersTo;
               item.timeReservationFrom = mCafe.timeReservationFrom;
               item.timeReservationTo   = mCafe.timeReservationTo;
               
               
               //Let's add GMT
               MCity mCity = getCity(mCafe.city);
               if(mCity == null){
               }
               else{
                  item.timeClose        -= mCity.GMT * 60;
                  item.timeOpen         -= mCity.GMT * 60;
                  item.timeCloseWeekend -= mCity.GMT * 60;
                  item.timeOpenWeekend  -= mCity.GMT * 60;
                  
                  item.timeCloseMo      -= mCity.GMT * 60;
                  item.timeOpenMo       -= mCity.GMT * 60;
                  item.timeCloseTu      -= mCity.GMT * 60;
                  item.timeOpenTu       -= mCity.GMT * 60;
                  item.timeCloseWe      -= mCity.GMT * 60;
                  item.timeOpenWe       -= mCity.GMT * 60;
                  item.timeCloseTh      -= mCity.GMT * 60;
                  item.timeOpenTh       -= mCity.GMT * 60;
                  item.timeCloseFr      -= mCity.GMT * 60;
                  item.timeOpenFr       -= mCity.GMT * 60;
                  item.timeCloseSa      -= mCity.GMT * 60;
                  item.timeOpenSa       -= mCity.GMT * 60;
                  item.timeCloseSu      -= mCity.GMT * 60;
                  item.timeOpenSu       -= mCity.GMT * 60;

                  
                  //They are nullable
                  if(item.timeOrdersFrom == null){
                  }
                  else{
                     item.timeOrdersFrom -= mCity.GMT * 60;
                  }
                  if(item.timeOrdersTo == null){
                  }
                  else{
                     item.timeOrdersTo -= mCity.GMT * 60;
                  }
                  if(item.timeReservationFrom == null){
                  }
                  else{
                     item.timeReservationFrom -= mCity.GMT * 60;
                  }
                  if(item.timeReservationTo == null){
                  }
                  else{
                     item.timeReservationTo -= mCity.GMT * 60;
                  }
               }
            }
         }
      }
      catch (Throwable e){
         response = new JRCafeListResponse(e);
      }

      updateStatistic(MAbstractStatistics.F_MENU);
      super.responseTime(response);
      return response;
   }





   // ---------------------------------------------------------------------------------------------
   // Images
   // ---------------------------------------------------------------------------------------------
   @GET
   @Path("/image/list/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   @SuppressWarnings({ "unchecked" })
   public JRCafeImageListResponse getFeedbacks(@PathParam("LANG") String sLang,
                                               @PathParam("TIME") long lTime){
      JRCafeImageListResponse response = new JRCafeImageListResponse();

      try{
         InterfaceConstants.LANGS lang = validateLang(sLang);

         for(MCafeImage mCafeImage : (List<MCafeImage>) MongoService.getListFrontEnd(
                  MCafeImage.class, lTime)){
            if(response.checkDeleted(mCafeImage)){
               JRCafeImageListResponse.JMItem item = response.add();
               item.fillIn(lang, mCafeImage);

               item.CID = mCafeImage.CID;
            }
         }
      }
      catch (Throwable e){
         response = new JRCafeImageListResponse(e);
      }

      updateStatistic(MAbstractStatistics.F_FEEDBACKS);
      super.responseTime(response);
      return response;
   }





   @SuppressWarnings("unchecked")
   @GET
   @Path("/menu/list/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRCourseListResponse listMenu(@PathParam("LANG") String sLang,
                                        @PathParam("TIME") long lTime){

      JRCourseListResponse response = new JRCourseListResponse();

      try{
         InterfaceConstants.LANGS lang = validateLang(sLang);

         for(MCourse mCourse : (List<MCourse>) MongoService.getListFrontEnd(MCourse.class, lTime)){

            if(response.checkDeleted(mCourse)){
               JRCourseListResponse.JMItem item = response.add();
               item.fillIn(lang, mCourse);
               item.category = mCourse.category;
               item.CID = mCourse.CID;
               item.price = mCourse.price;

               String sIngredients = mCourse.ingredient.toString();
               item.ingredients = sIngredients.substring(1, sIngredients.length() - 1);

               item.weight = mCourse.weight2.get(lang);
               item.delivery = mCourse.delivery;
            }
         }

      }
      catch (Throwable e){
         response = new JRCourseListResponse(e);
      }

      updateStatistic(MAbstractStatistics.F_MENU);
      super.responseTime(response);
      return response;
   }





   @GET
   @Path("/reserve/list/{SID}/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRReserveListResponse listReservation(@PathParam("SID")  String SID,
                                                @PathParam("LANG") String sLang,
                                                @PathParam("TIME") long lTime){

      JRReserveListResponse response = new JRReserveListResponse();

      try{
         checkSession(SID);
         InterfaceConstants.LANGS lang = validateLang(sLang);

         for(MReservation mReservation : MongoService.getReserves(super.UID, lTime)){
            if(response.checkDeleted(mReservation)){
               JRReserveListResponse.JMItem item = response.add();
               item.fillIn(mReservation);
               item.date = mReservation.date;
               item.CID = mReservation.CID;
               item.sits = mReservation.sits;
               item.comment = mReservation.comment.get(lang);
               item.confirmed = mReservation.confirmed;
            }
         }

      }
      catch (Throwable e){
         response = new JRReserveListResponse(e);
      }

      updateStatistic(MAbstractStatistics.F_MENU);
      super.responseTime(response);
      return response;
   }





   // ---------------------------------------------------------------------------------------------
   // add new reserver
   // ---------------------------------------------------------------------------------------------
   @GET
   @Path("/reserve/new/{SID}/{date}/{CID}/{sits}/{lang}/{comment}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JREmptyResponse newReservation(@PathParam("SID") String SID,
                                         @PathParam("date") long date,
                                         @PathParam("CID") int CID,
                                         @PathParam("sits") int iSits,
                                         @PathParam("lang") String sLang,
                                         @PathParam("comment") String sComment){
      JREmptyResponse response = new JREmptyResponse();

      try{
         checkSession(SID);

         MCafe mCafe = MongoService.getExceptionable(MCafe.class, CID);
         InterfaceConstants.LANGS lang = validateLang(sLang);

         MReservation mReservation = new MReservation();
         mReservation.ID = MongoService.getUniqueID(MReservation.class);
         mReservation.UID = super.UID;
         mReservation.ownerID = mCafe.ownerID;
         mReservation.CID = CID;
         mReservation.date = date;
         mReservation.sits = iSits;
         mReservation.comment.put(lang, sComment);

         MongoService.save(mReservation);
         

         HashMap<String, Object> map = new HashMap<String, Object>();
         map.put("cafe_name",   mCafe.name);
         
         MUser mUser = MongoService.get(MUser.class, UID);
         map.put("user_login",  mUser.login);
         map.put("user_name",   mUser.name);
         map.put("user_phone",  mUser.phone);
         
         map.put("sits",        iSits);
         map.put("date",        new SimpleDateFormat("HH:mm dd-MM-yyyy").format(date));
         map.put("comment",     sComment);

         
         String sNewReservation = VelocityProc.run("new_reserve.vm", map); 

         //To Admin
         Mailer.sendMail(ServerConstants.getRobot(),
                         ServerConstants.getEmailAddressSystemAdmin(),
                         "Новый резерв в " + mCafe.name,
                         sNewReservation);
         
         //To cafe owner
         MUser mUserCafeOwner = MongoService.get(MUser.class, mCafe.ownerID);
         
         log.info(LOG + "Email Notification for Admin=" + mUserCafeOwner.ID + " is " + (mUserCafeOwner.hasEmailNotifications ? "ON" : "OFF"));
         
         if(mUserCafeOwner.hasEmailNotifications){
            Mailer.sendMail(ServerConstants.getRobot(),
                            mUserCafeOwner.login,
                            "Новый резерв в " + mCafe.name,
                            sNewReservation);
         }
      }
      catch (Throwable e){
         response = new JREmptyResponse(e);
      }

      updateStatistic(MAbstractStatistics.F_FEEDBACK_NEW);
      super.responseTime(response);
      return response;
   }





   // ---------------------------------------------------------------------------------------------
   // add new order
   // ---------------------------------------------------------------------------------------------
   @GET
   @Path("/order/new/{SID}/{CID}/{date}/{AID}/{lang}/{comment}/{paths:.+}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRNewOrderResponse newOrder(@PathParam("SID")     String SID,
                                      @PathParam("CID")     int CID,
                                      @PathParam("date")    long date,
                                      @PathParam("AID")     int AID,
                                      @PathParam("lang")    String sLang,
                                      @PathParam("comment") String sComment,
                                      @PathParam("paths")   List<PathSegment> uglyPath){
      JRNewOrderResponse response = new JRNewOrderResponse();

      List<String> listOrderItems = uglyPath2Array(uglyPath);

      try{
         checkSession(SID);

         MCafe mCafe = MongoService.getExceptionable(MCafe.class, CID);

         if(AID > 0){
            MongoService.getExceptionable(MSale.class, AID);
         }

         InterfaceConstants.LANGS lang = validateLang(sLang);

         MOrder mOrder = new MOrder();
         mOrder.ID = MongoService.getUniqueID(MOrder.class);
         response.OID = mOrder.ID; 
         
         mOrder.CID = CID;

         if(AID > 0){
            mOrder.AID = AID;
         }

         mOrder.UID = super.UID;
         mOrder.comment.put(lang, sComment);
         mOrder.ownerID = mCafe.ownerID;

         int iPrice = 0;
         List<VOrderItem> listVelocityItems = new ArrayList<VOrderItem>();

         while (listOrderItems.size() > 0){
            int MID = Integer.parseInt(listOrderItems.remove(0));
            int iQuantity = Integer.parseInt(listOrderItems.remove(0));
            
            MCourse mCourse = (MCourse) MongoService.getExceptionable(MCourse.class, MID);

            MOrderItem mOrderItem = new MOrderItem();
            mOrderItem.ID       = MongoService.getUniqueID(MOrderItem.class);
            mOrderItem.OID      = mOrder.ID;
            mOrderItem.MID      = MID;
            mOrderItem.quantity = iQuantity;
            mOrderItem.price    = mCourse.price * iQuantity;
            MongoService.save(mOrderItem);
            
            
            iPrice += mOrderItem.price;
            
            VOrderItem vOrderItem = new VOrderItem(mCourse.name,
                                                   iQuantity,
                                                   "" + new Float(mCourse.price) / 100);
            listVelocityItems.add(vOrderItem);
         }

         mOrder.price = iPrice;
         MongoService.save(mOrder);

         MongoOrderService.racalculteCounters(mOrder);
         
         
         HashMap<String, Object> map = new HashMap<String, Object>();
         map.put("cafe_name",   mCafe.name);
         
         MUser mUser = MongoService.get(MUser.class, UID);
         map.put("user_login",  mUser.login);
         map.put("user_name",   mUser.name);
         map.put("user_phone",  mUser.phone);
         
         map.put("comment",     sComment);
         
         map.put("items",       listVelocityItems);

         map.put("price",       "" + new Float(iPrice) / 100);
         
         
         String sNewOrder = VelocityProc.run("new_order.vm", map); 
         
         //To Admin
         Mailer.sendMail(ServerConstants.getRobot(),
                         ServerConstants.getEmailAddressSystemAdmin(),
                         "Новый заказ в " + mCafe.name,
                         sNewOrder);
         
         //To cafe owner
         MUser mUserCafeOwner = MongoService.get(MUser.class, mCafe.ownerID);
         
         log.info(LOG + "Email Notification for Admin=" + mUserCafeOwner.ID + " is " + (mUserCafeOwner.hasEmailNotifications ? "ON" : "OFF"));
         
         if(mUserCafeOwner.hasEmailNotifications){
            Mailer.sendMail(ServerConstants.getRobot(),
                            mUserCafeOwner.login,
                            "Новый заказ в " + mCafe.name,
                            sNewOrder);
         }
      }
      catch (Throwable e){
         response = new JRNewOrderResponse(e);
      }

      updateStatistic(MAbstractStatistics.F_ORDER_NEW);
      super.responseTime(response);
      return response;
   }






   public static class VOrderItem{
      private final Map<InterfaceConstants.LANGS, String> name;
      private final int    quantity;
      private final String price;
      
      public VOrderItem(Map<InterfaceConstants.LANGS, String> name, int quantity, String price){
         this.name = name;
         this.quantity = quantity;
         this.price = price;
      }
      public Map<InterfaceConstants.LANGS, String> getName(){
         return name;
      }
      public int getQuantity(){
         return quantity;
      }
      public String getPrice(){
         return price;
      }
   }






   // ---------------------------------------------------------------------------------------------
   // update order
   // ---------------------------------------------------------------------------------------------
   @GET
   @Path("/order/update/{SID}/{OID}/{CID}/{date}/{AID}/{lang}/{comment}/{paths:.+}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JREmptyResponse updateOrder(@PathParam("SID")     String SID,
                                      @PathParam("OID")     int OID,
                                      @PathParam("CID")     int CID,
                                      @PathParam("date")    long date,
                                      @PathParam("AID")     int AID,
                                      @PathParam("lang")    String sLang,
                                      @PathParam("comment") String sComment,
                                      @PathParam("paths")   List<PathSegment> uglyPath){
      JREmptyResponse response = new JREmptyResponse();

      List<String> listOrders = uglyPath2Array(uglyPath);

      try{
         checkSession(SID);

         MCafe mCafe = MongoService.getExceptionable(MCafe.class, CID);
         MongoService.getExceptionable(MSale.class, AID);

         InterfaceConstants.LANGS lang = validateLang(sLang);

         MOrder mOrder = MongoService.get(MOrder.class, OID);
         mOrder.CID = CID;

         if(AID > 0){
            mOrder.AID = AID;
         }

         mOrder.UID = super.UID;
         mOrder.comment.put(lang, sComment);
         mOrder.ownerID = mCafe.ownerID;

         List<MOrderItem> listOrderItems = MongoService.ds.find(MOrderItem.class)
                  .filter(MOrderItem.F_OID, OID).asList();

         for(MOrderItem mOrderItem : listOrderItems){
            mOrderItem.deleted = true;
         }

         while (listOrders.size() > 0){
            int MID = Integer.parseInt(listOrders.remove(0));
            int iQuantity = Integer.parseInt(listOrders.remove(1));

            MOrderItem mOrderItem;
            if(listOrderItems.size() > 0){
               mOrderItem = listOrderItems.remove(0);
            }
            else{
               mOrderItem = new MOrderItem();
               mOrderItem.ID = MongoService.getUniqueID(MOrderItem.class);
            }

            mOrderItem.OID = mOrder.ID;
            mOrderItem.MID = MID;
            mOrderItem.quantity = iQuantity;
            MongoService.save(mOrderItem);
         }

         for(MOrderItem mOrderItem : listOrderItems){
            MongoService.save(mOrderItem);
         }

         MongoService.save(mOrder);
      }
      catch (Throwable e){
         response = new JREmptyResponse(e);
      }

      // updateStatistic(MAbstractStatistics.F_ORDER_NEW);
      super.responseTime(response);
      return response;
   }





   // ---------------------------------------------------------------------------------------------
   // update order
   // ---------------------------------------------------------------------------------------------
   @GET
   @Path("/order/list/{SID}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JROrderListResponse listOrders(@PathParam("SID") String SID){
      JROrderListResponse response = new JROrderListResponse();

      try{
         checkSession(SID);

         List<MOrder> listOrders = MongoService.ds.find(MOrder.class)
                  .filter(MOrder.F_UID, super.UID).asList();
         for(MOrder mOrder : listOrders){
            JROrderListResponse.JMOrder jmOrder = response.add();
            jmOrder.ID = mOrder.ID;
            jmOrder.CID = mOrder.CID;
            jmOrder.AID = mOrder.AID;

            List<MOrderItem> listOrderItems = MongoService.ds.find(MOrderItem.class)
                     .filter(MOrderItem.F_OID, mOrder.ID).asList();

            for(MOrderItem mOrderItem : listOrderItems){
               JROrderListResponse.JMOrder.JMMeal jmMeal = jmOrder.add();
               jmMeal.IID = mOrderItem.MID;
               jmMeal.quantity = mOrderItem.quantity;
            }
         }
      }
      catch (Throwable e){
         response = new JROrderListResponse(e);
      }

      // updateStatistic(MAbstractStatistics.F_ORDER_NEW);
      super.responseTime(response);
      return response;
   }


   
   
   
   
   
   // ---------------------------------------------------------------------------------------------
   // add new order
   // ---------------------------------------------------------------------------------------------
   @GET
   @Path("/order/delivery/set/{SID}/{OID}/{CITY}/{STREET}/{BUILDING}/{APARTMENT}/{PHONE}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JREmptyResponse setDeliveryAddress(@PathParam("SID")       String SID,
                                             @PathParam("OID")       int    OID,
                                             @PathParam("CITY")      int    CityID,
                                             @PathParam("STREET")    String sStreet,
                                             @PathParam("BUILDING")  String sBuilding,
                                             @PathParam("APARTMENT") String sApartment,
                                             @PathParam("PHONE")     String sPhone){
      
      
      
      JREmptyResponse response = new JREmptyResponse();

      try{
         checkSession(SID);
         
         MOrder mOrder = MongoService.getExceptionable(MOrder.class, OID);
         if(mOrder.UID == UID){
            mOrder.deliveryCity      = MongoService.getExceptionable(MCity.class, CityID).ID;;
            mOrder.deliveryStreet    = sStreet;
            mOrder.deliveryBuilding  = sBuilding;
            mOrder.deliveryApartment = sApartment;
            mOrder.deliveryPhone     = sPhone;
            MongoService.save(mOrder);
         }
         else{
            throw new AccessDeniedException(MOrder.class, mOrder.ID);
         }
      }
      catch (Throwable e){
         response = new JREmptyResponse(e);
      }

      // updateStatistic(MAbstractStatistics.F_ORDER_NEW);
      super.responseTime(response);
      return response;
   }
   
   
   
   
   
   
   
   



   // ---------------------------------------------------------------------------------------------
   // Descriptors
   // ---------------------------------------------------------------------------------------------

   @GET
   @Path("/ingredients/list/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRDescriptorListResponse ingredients(@PathParam("LANG") String sLang,
                                               @PathParam("TIME") long lTime){

      return getDescriptors(MIngredient.class, sLang, lTime);
   }





   @GET
   @Path("/menu/category/list/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRDescriptorListResponse courseCategories(@PathParam("LANG") String sLang,
                                                    @PathParam("TIME") long lTime){

      return getDescriptors(MCourseCategory.class, sLang, lTime);
   }





   @GET
   @Path("/type/list/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRDescriptorListResponse cafeTypes(@PathParam("LANG") String sLang,
                                             @PathParam("TIME") long lTime){

      return getDescriptors(MCafeType.class, sLang, lTime);
   }





   @GET
   @Path("/service/list/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRDescriptorListResponse serviceTypes(@PathParam("LANG") String sLang,
                                                @PathParam("TIME") long lTime){

      return getDescriptors(MServiceType.class, sLang, lTime);
   }
   
   
   
   @GET
   @Path("/cuisine/list/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRDescriptorListResponse cuisines(@PathParam("LANG") String sLang,
                                            @PathParam("TIME") long lTime){

      return getDescriptors(MCuisine.class, sLang, lTime);
   }
   
   
   
   @GET
   @Path("/req/list/{LANG}/{TIME}")
   @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
   public JRDescriptorListResponse faceControl(@PathParam("LANG") String sLang,
                                               @PathParam("TIME") long lTime){

      return getDescriptors(MFaceControl.class, sLang, lTime);
   }
   
   





   @SuppressWarnings({ "rawtypes", "unchecked" })
   private JRDescriptorListResponse getDescriptors(Class clas, String sLang, long lTime){
      JRDescriptorListResponse response = new JRDescriptorListResponse();

      try{
         InterfaceConstants.LANGS lang = validateLang(sLang);

         for(MAbstractDescriptor mAbstractDescriptor :
                            (List<MAbstractDescriptor>) MongoService.getListFrontEnd(clas, lTime)){

            if(response.checkDeleted(mAbstractDescriptor)){
               JRDescriptorListResponse.JMItem item = response.add();
               item.fillIn(lang, mAbstractDescriptor);
            }
         }
      }
      catch (Throwable e){
         response = new JRDescriptorListResponse(e);
      }

      updateStatistic(MAbstractStatistics.F_MENU);
      super.responseTime(response);
      return response;
   }
}
