/** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    if (logger.isDebugEnabled()) {
      logger.debug("doGet(HttpServletRequest, HttpServletResponse) - start");
    }

    response.setHeader("Content-Type", "text/html; charset=UTF-8");
    Params params = Params.of(request);

    PrintWriter out = null;
    try {
      out = response.getWriter();
      _handleRequest(params, request, response, out);
    } catch (IOException e) {
      e.printStackTrace();
      logger.error("doGet() failed.", e);
    } catch (JSONException e) {
      e.printStackTrace();
      logger.error("doGet() failed.", e);
    } catch (Exception e) {
      e.printStackTrace();
      logger.error("doGet() failed.", e);
    } finally {
      if (null != out) {
        try {
          out.close();
        } catch (Exception e) {
          logger.error("doGet() failed.", e);
        }
        out = null;
      }
    }

    if (logger.isDebugEnabled()) {
      logger.debug("doGet(HttpServletRequest, HttpServletResponse) - end");
    }
  }
  private void _handleRequest(
      Params params, HttpServletRequest request, HttpServletResponse response, PrintWriter out)
      throws Exception {

    logger.debug("params={}", params.toString());

    String g_country = params.trimParam("country");
    double g_lat = params.getDoubleParam("lat", -999);
    double g_lng = params.getDoubleParam("lng", -999);
    Date g_begin = params.getDateParam("begin_time");
    Date g_end = params.getDateParam("end_time");
    String sample_rate = params.getParam("sample_rate");

    DateRange drange = null;
    if (null == g_begin && null == g_end) {

    } else if (null == g_begin) {
      drange = DateRange.is(g_end);
    } else if (null == g_end) {
      drange = DateRange.is(g_begin);
    } else {
      drange = DateRange.between(g_begin, g_end);
    }

    HashMap<String, List<?>> map = new HashMap<String, List<?>>(4);

    String g_columns = params.getParam("fields", "");
    String[] columns = g_columns.split(",");

    ArrayList<Long> idxList = new ArrayList<Long>();
    map.put("index", idxList);
    ArrayList<ArrayList<?>> dataList = new ArrayList<ArrayList<?>>();
    map.put("data", dataList);

    MongoAPI api = new MongoAPI(Console.mongo.getDB("weather1"));
    ArrayList<Station> stations = stationService.queryList(g_country, g_lat, g_lng);

    ArrayList<String> exp_cols = new ArrayList<String>(3 * columns.length);
    exp_cols.add("station");
    for (int i = 0, lenCol = columns.length; i < lenCol; ++i) {
      String col = columns[i];
      if ("date".equals(col)) {
        exp_cols.add(col);
      } else if ("time".equals(col)) {
      } else {
        exp_cols.add("min_" + col);
        exp_cols.add("max_" + col);
        exp_cols.add("avg_" + col);
      }
    }
    map.put("columns", exp_cols);

    if ("d".equals(sample_rate)) {
      // daily base
      for (Station s : stations) {
        String station = s.getId();
        for (int year = drange.first.year.value, end = drange.last.year.value;
            year <= end;
            ++year) {
          Result<ArrayList<ArrayList<Object>>> result =
              api.queryDailyWeatherByStation(year, station, drange, columns);
          if (result.positive()) {
            for (int i = 0, lenData = result.data.size(); i < lenData; ++i) {
              ArrayList<Object> arr = result.data.get(i);
              String datetime = String.valueOf(arr.remove(arr.size() - 1));
              DateTime dt = DateTime.valueOf(datetime);
              idxList.add(dt.timestamp);
              dataList.add(arr);
            }
          }
        }
      }
    } else if ("w".equals(sample_rate)) {
      // weekly base
      for (Station s : stations) {
        String station = s.getId();
        for (int year = drange.first.year.value, end = drange.last.year.value;
            year <= end;
            ++year) {
          Result<ArrayList<ArrayList<Object>>> result =
              api.queryWeeklyWeatherByStation(year, station, drange, columns);
          if (result.positive()) {
            for (int i = 0, lenData = result.data.size(); i < lenData; ++i) {
              ArrayList<Object> arr = result.data.get(i);
              String datetime = String.valueOf(arr.remove(arr.size() - 1));
              DateTime dt = DateTime.valueOf(datetime);
              idxList.add(dt.timestamp);
              dataList.add(arr);
            }
          }
        }
      }
    } else if ("m".equals(sample_rate)) {
      for (Station s : stations) {
        String station = s.getId();
        for (int year = drange.first.year.value, end = drange.last.year.value;
            year <= end;
            ++year) {
          Result<ArrayList<ArrayList<Object>>> result =
              api.queryMonthlyWeatherByStation(year, station, drange, columns);
          if (result.positive()) {
            for (int i = 0, lenData = result.data.size(); i < lenData; ++i) {
              ArrayList<Object> arr = result.data.get(i);
              String datetime = String.valueOf(arr.remove(arr.size() - 1));
              DateTime dt = DateTime.valueOf(datetime);
              idxList.add(dt.timestamp);
              dataList.add(arr);
            }
          }
        }
      }
    } else {

      for (Station s : stations) {
        String station = s.getId();
        for (int year = drange.first.year.value, end = drange.last.year.value;
            year <= end;
            ++year) {
          Result<ArrayList<ArrayList<Object>>> result =
              api.queryDailyWeatherByStation(year, station, drange, columns);
          if (result.positive()) {
            for (int i = 0, lenData = result.data.size(); i < lenData; ++i) {
              ArrayList<Object> arr = result.data.get(i);
              String datetime = String.valueOf(arr.remove(arr.size() - 1));
              DateTime dt = DateTime.valueOf(datetime);
              idxList.add(dt.timestamp);
              dataList.add(arr);
            }
          }
        }
      }

      //			// raw base
      //			map.put("columns", Arrays.asList(columns));
      //
      //			for (Station s: stations) {
      //				String station = s.getId();
      //				for (int year = drange.first.year.value, end = drange.last.year.value; year <= end;
      // ++year) {
      //					Result<ArrayList<ArrayList<Object>>> result = api.queryWeatherByStation(year, station,
      // drange, columns);
      //					if (result.positive()) {
      //						for (int i = 0, lenData =  result.data.size(); i < lenData; ++i) {
      //							ArrayList<Object> arr = result.data.get(i);
      //							String datetime = String.valueOf(arr.remove(arr.size()-1));
      //							DateTime dt = DateTime.valueOf(datetime);
      //							idxList.add(dt.timestamp);
      //							dataList.add(arr);
      //						}
      //					}
      //				}
      //			}
    }

    JSONObject json = JsonUtil.getBasicJson(ErrorCode.ok());
    String resStr = "{}";
    if (!dataList.isEmpty()) {
      resStr = JsonUtil.makeJsonize(map).toString();
    }
    JsonUtil.addField(json, "data", resStr);
    JsonUtil.addField(json, "version", VERSION);
    json.write(out);
  }