package com.dev.swms.server.web.servlet;

import com.dev.energy.client.config.page.TableConfig;
import com.dev.energy.server.config.UniConfig;
import com.dev.energy.server.config.ui.engine.DataSource;
import com.dev.energy.server.config.ui.engine.GetTableConfig;
import com.dev.energy.server.config.ui.engine.Page;
import com.dev.energy.server.exception.EnergyServerRuntimeException;
import com.dev.energy.server.model.Entity;
import com.dev.energy.server.service.ValueListQueryManager;
import com.dev.energy.server.service.security.SecurityFilter;
import com.dev.energy.server.servlet.BaseHttpServlet;
import com.dev.energy.server.util.DataSourceParamUtil;
import com.dev.swms.server.web.servlet.export.ExportExcelGenerator;
import com.dev.swms.server.web.servlet.export.impl.XLSExportGenerator;

import java.io.IOException;
import java.net.URLDecoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;

public class SwmsExportGridServlet extends BaseHttpServlet {

   private static final long serialVersionUID = 1L;
   private final DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");


   public void process(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
	   System.out.println("export join.....");
	   res.setContentType("text/html; charset=UTF-8");
	   req.setCharacterEncoding("UTF-8");
	   res.setCharacterEncoding("UTF-8");
      UniConfig uniConfig = (UniConfig)this.ac.getBean("uniConfig");
      String exportExcelType = req.getParameter("exportType");
      if(StringUtils.isNotEmpty(exportExcelType)) {
         exportExcelType = URLDecoder.decode(StringUtils.substring(exportExcelType, 0, exportExcelType.length() - 3));
      }

      Map map = req.getParameterMap();
      HashMap params = new HashMap();
      Iterator sf = map.keySet().iterator();

      String pageId;
      String ids;
      String hql;
      while(sf.hasNext()) {
         pageId = (String)sf.next();
         String[] dataSourceType = (String[])map.get(pageId);
         ids = null;
         if(dataSourceType != null && dataSourceType.length > 0) {
            ids = dataSourceType[0];
            System.out.println("parameter:"+ids);
            System.out.println("parameter2:");
            if(ids != null) {
               ids = URLDecoder.decode(ids);
            }
         }

         if(ids == null) {
            params.put(pageId, ids);
         } else {
            String page = "^\\[\\w+(,\\w+)*\\]\\w*$";
            System.out.println("===="+ids);
            String gc;
            ArrayList tableConfig;
            int dataSourceParamUtil;
            String[] var17;
            int beans;
            if(Pattern.matches(page, ids.replaceAll("\\s*", ""))) {
               gc = StringUtils.substringBetween(ids, "[", "]");
               tableConfig = new ArrayList();
               beans = (var17 = gc.split(",")).length;

               for(dataSourceParamUtil = 0; dataSourceParamUtil < beans; ++dataSourceParamUtil) {
                  hql = var17[dataSourceParamUtil];
                  tableConfig.add(Long.valueOf(hql.trim()));
               }

               params.put(pageId, tableConfig);
            } else if(!ids.endsWith("_s_")) {
               if(ids.endsWith("_b_")) {
                  Boolean var24 = new Boolean(ids.substring(0, ids.length() - 3));
                  params.put(pageId, var24);
               } else if(ids.endsWith("_i_")) {
                  Integer var25 = new Integer(ids.substring(0, ids.length() - 3));
                  params.put(pageId, var25);
               } else if(ids.endsWith("_l_")) {
                  Long var27 = new Long(ids.substring(0, ids.length() - 3));
                  params.put(pageId, var27);
               } else if(ids.endsWith("_t_")) {
                  Date var28 = null;

                  try {
                     if(ids.indexOf(" ") > 0) {
                        SimpleDateFormat var29 = new SimpleDateFormat("yyyy-MM-dd hh:mm");
                        var28 = var29.parse(ids);
                     } else {
                        var28 = this.dateFormatter.parse(ids.substring(0, ids.length() - 3));
                     }
                  } catch (Exception var20) {
                     var20.printStackTrace();
                  }

                  params.put(pageId, var28);
               } else if(ids.endsWith("_d_")) {
                  Double var31 = new Double(ids.substring(0, ids.length() - 3));
                  params.put(pageId, var31);
               } else if(ids.endsWith("_f_")) {
                  Float var30 = new Float(ids.substring(0, ids.length() - 3));
                  params.put(pageId, var30);
               } else {
                  params.put(pageId, ids);
               }
            } else {
               gc = ids.substring(0, ids.length() - 3);
               if(!"ids".equals(pageId) && !"parentIds".equals(pageId)) {
                  params.put(pageId, gc);
               } else {
                  tableConfig = new ArrayList();
                  beans = (var17 = gc.split(",")).length;

                  for(dataSourceParamUtil = 0; dataSourceParamUtil < beans; ++dataSourceParamUtil) {
                     hql = var17[dataSourceParamUtil];
                     tableConfig.add(Long.valueOf(hql));
                  }

                  params.put(pageId, tableConfig);
               }
            }
         }
      }

      SecurityFilter var21 = (SecurityFilter)req.getSession(false).getAttribute("securityFilterInSession");
      pageId = req.getParameter("pageId");
      String var22 = req.getParameter("dataSourceType");
      ids = req.getParameter("ids");
      if(ids != null && ids.endsWith("_s_")) {
         ids = ids.substring(0, ids.length() - 3);
      } else {
         ids = null;
      }

      Page var23 = uniConfig.getPage(var21.getReferenceModel(), pageId);
      if(var23 instanceof GetTableConfig) {
         GetTableConfig var34 = (GetTableConfig)var23;
         TableConfig var26 = var34.generateTableConfig(var21);
         hql = var26.getHql();
         if(!StringUtils.isEmpty(ids)) {
            hql = this.adjustExporHql(hql, ids);
         }

         DataSourceParamUtil var33 = (DataSourceParamUtil)this.ac.getBean("dataSourceParamUtil");
         if(params.containsKey("ids")) {
            params.remove("ids");
         }

         params.putAll(var33.dealParams(var21.getHqlParams(pageId)));
         hql = this.convertGlobalParamToHql(hql, params, req);
         hql = this.removeHqlWithNullParam(hql, params);
         hql = this.formateHql(hql);
         if(var26.getDataSourceType().equals(DataSource.HQL_TYPE)) {
            if(hql.toUpperCase().indexOf("ORDER BY") == -1) {
               hql = hql + var26.getSortHql();
            } else if(!StringUtils.isEmpty(var26.getSortHql())) {
               hql = hql + var26.getSortHql().replace("ORDER BY", ",");
            }
         }

         if(var22.equals(DataSource.HQL_TYPE)) {
            Map var32 = this.ac.getBeansOfType(ExportExcelGenerator.class);

            XLSExportGenerator xls=new XLSExportGenerator();
            try {
            	  ValueListQueryManager gridQueryManager = (ValueListQueryManager)this.ac.getBean("valueListQueryManager");
            	xls.exportExcel(ac,hql, params, var26, res, var21.getReferenceModel(), var21.getLocale());
               //((ExportExcelGenerator)var32.get(exportExcelType == null?"XLS":exportExcelType)).exportExcel(hql, params, var26, res, var21.getReferenceModel(), var21.getLocale());
            } catch (IOException var18) {
            	var18.printStackTrace();
               ;
            } catch (Exception var19) {
            	var19.printStackTrace();
               ;
            }
         }

      }
   }

   private String adjustExporHql(String hql, String ids) {
      StringTokenizer st = new StringTokenizer(hql);
      String result = "";
      String entityId = "";

      while(st.hasMoreElements()) {
         String whereIdx = st.nextToken();
         if(whereIdx.contains(".id")) {
            entityId = whereIdx;
            break;
         }
      }

      entityId = StringUtils.substring(entityId, 0, entityId.indexOf(".id") + 3);
      int whereIdx1 = StringUtils.upperCase(hql).indexOf("WHERE");
      int oderByIdx = StringUtils.upperCase(hql).indexOf("ORDER BY");
      int groupByIdx = StringUtils.upperCase(hql).indexOf("GROUP BY");
      String oderBy = "";
      String groupBy = "";
      if(oderByIdx > 0) {
         if(groupByIdx > 0) {
            oderBy = oderBy + StringUtils.substring(hql, oderByIdx, groupByIdx);
            groupBy = groupBy + StringUtils.substring(hql, groupByIdx, hql.length());
         } else {
            oderBy = oderBy + StringUtils.substring(hql, oderByIdx, hql.length());
         }
      }

      if(whereIdx1 < 0) {
         return oderByIdx != -1?StringUtils.substring(hql, 0, oderByIdx) + " WHERE " + entityId + " in (" + ids + ") and " + oderBy + " " + groupBy:(groupByIdx != -1?StringUtils.substring(hql, 0, groupByIdx) + " WHERE " + entityId + " in (" + ids + ") and " + oderBy + " " + groupBy:hql + " WHERE " + entityId + " in (" + ids + ") " + oderBy + " " + groupBy);
      } else {
         String where = hql.substring(whereIdx1, whereIdx1 + 6);
         result = StringUtils.replaceOnce(hql, where, " where " + entityId + " in (" + ids + ")  and ");
         return result;
      }
   }

   private String convertGlobalParamToHql(String hql, Map params, HttpServletRequest req) {
      String sessionParam;
      Object sessionValue;
      for(String _hql = StringUtils.substringBetween(hql, "/~", "~/"); !StringUtils.isEmpty(_hql) && !StringUtils.isEmpty(StringUtils.substringBetween(_hql, "#{", "}")); _hql = StringUtils.substringBetween(hql, "/~", "~/")) {
         sessionParam = StringUtils.substringBetween(_hql, "#{", "}");
         if(!StringUtils.isEmpty(sessionParam)) {
            sessionValue = req.getSession(false).getAttribute(sessionParam);
            if(sessionValue == null) {
               sessionValue = ((UniConfig)this.ac.getBean("uniConfig")).getGlobalParam(sessionParam).getClientGlobal();
            }

            if(sessionValue == null) {
               throw new EnergyServerRuntimeException("Session parameter [" + sessionParam + "] does contain corresponding value in session attribute");
            }

            if(!(sessionValue instanceof Entity) && !(sessionValue instanceof Collection)) {
               if(sessionValue instanceof Number) {
                  hql = StringUtils.replace(hql, "#{" + sessionParam + "}", sessionValue.toString());
               } else {
                  hql = StringUtils.replace(hql, "#{" + sessionParam + "}", "\'" + sessionValue.toString() + "\'");
               }

               params.put(sessionParam, sessionValue);
            } else {
               hql = StringUtils.replace(hql, "#{" + sessionParam + "}", "{" + sessionParam + "}");
               params.put(sessionParam, sessionValue);
            }

            StringUtils.replace(hql, "/~" + _hql + "~/", StringUtils.substring(_hql, _hql.indexOf(":") + 1));
         }
      }

      for(sessionParam = StringUtils.substringBetween(hql, "#{", "}"); !StringUtils.isEmpty(sessionParam); sessionParam = StringUtils.substringBetween(hql, "#{", "}")) {
         sessionValue = req.getSession(false).getAttribute(sessionParam);
         if(sessionValue == null) {
            sessionValue = ((UniConfig)this.ac.getBean("uniConfig")).getGlobalParam(sessionParam).getClientGlobal();
         }

         if(sessionValue == null) {
            throw new EnergyServerRuntimeException("Session parameter [" + sessionParam + "] does contain corresponding value in session attribute");
         }

         if(!(sessionValue instanceof Entity) && !(sessionValue instanceof Collection)) {
            if(sessionValue instanceof Number) {
               hql = StringUtils.replace(hql, "#{" + sessionParam + "}", sessionValue.toString());
            } else {
               hql = StringUtils.replace(hql, "#{" + sessionParam + "}", "\'" + sessionValue.toString() + "\'");
            }
         } else {
            hql = StringUtils.replace(hql, "#{" + sessionParam + "}", "{" + sessionParam + "}");
            params.put(sessionParam, sessionValue);
         }
      }

      return hql;
   }

   private String removeHqlWithNullParam(String hql, Map params) {
      for(String _hql = StringUtils.substringBetween(hql, "/~", "~/"); StringUtils.isNotEmpty(_hql); _hql = StringUtils.substringBetween(hql, "/~", "~/")) {
         String param = StringUtils.substring(_hql, 0, _hql.indexOf(":")).trim();
         Object o = params.get(param);
         if(o != null && !"".equals(o)) {
            if(o instanceof Collection && (((Collection)o).isEmpty() || ((Collection)o).size() == 0)) {
               params.remove(param);
               hql = StringUtils.remove(hql, "/~" + _hql + "~/");
            }
         } else {
            params.remove(param);
            hql = StringUtils.remove(hql, "/~" + _hql + "~/");
         }

         hql = StringUtils.replace(hql, "/~" + _hql + "~/", StringUtils.substring(_hql, _hql.indexOf(":") + 1));
      }

      return hql;
   }

   private String formateHql(String hql) {
      String hqlStatement = hql;
      int leftToenailIndex = hql.indexOf("(");
      if(leftToenailIndex != -1) {
         hqlStatement = StringUtils.replace(hql, "(", " ( ");
      }

      int rightToenailIndex = hqlStatement.indexOf(")");
      if(rightToenailIndex != -1) {
         hqlStatement = StringUtils.replace(hqlStatement, ")", " ) ");
      }

      int enterIndex = hqlStatement.indexOf("\n");
      if(enterIndex != -1) {
         hqlStatement = StringUtils.replace(hqlStatement, "\n", " \n");
      }

      return hqlStatement;
   }
}
