package coreservlets.filters;

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

/** Filtr zapisuje informacje o wywoływaniu strony
 *  w niecodziennych godzinach.
 *  <P>
 *  Taken from Core Servlets and JavaServer Pages Volume II
 *  from Prentice Hall and Sun Microsystems Press,
 *  http://volume2.coreservlets.com/.
 *  (C) 2007 Marty Hall, Larry Brown, and Yaakov Chaikin;
 *  may be freely used or adapted.
 */
public class LateAccessFilter implements Filter {
  private FilterConfig config;
  private ServletContext context;
  private int startTime, endTime;
  private DateFormat formatter;
  
  public void doFilter(ServletRequest request,
                       ServletResponse response,
                       FilterChain chain)
      throws ServletException, IOException {
    HttpServletRequest req = (HttpServletRequest)request;
    GregorianCalendar calendar = new GregorianCalendar();
    int currentTime = calendar.get(Calendar.HOUR_OF_DAY);
    if (isUnusualTime(currentTime, startTime, endTime)) {
      context.log("OSTRZEŻENIE: " +
                  req.getRemoteHost() +
                  " wywołana " +
                  req.getRequestURL() +
                  " w dniu " + 
                  formatter.format(calendar.getTime()));
    }
    chain.doFilter(request,response);
  }

  public void init(FilterConfig config)
      throws ServletException {
    this.config = config;
    context = config.getServletContext();
    formatter =
      DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
                                     DateFormat.MEDIUM);
    try {
      startTime =
        Integer.parseInt(config.getInitParameter("startTime"));
      endTime =
        Integer.parseInt(config.getInitParameter("endTime"));
    } catch(NumberFormatException nfe) { // Zły format albo null
      // Domyślnie jako niecodzienne traktowane są godziny
      // między 22 i 6 rano.
      startTime = 22;
      endTime = 6;
    }
  }
  
  public void destroy() {}

  // Czy aktualna godzina należy do zakresu godzin
  // wyznaczających niecodzienną porę?
  private boolean isUnusualTime(int currentTime,
                                int startTime,
                                int endTime) {
    // Jeśli godzina początkowa jest mniejsza niż godzina końcowa
    // (czyli są to godziny tego samego dnia), wówczas
    // godzina bieżąca jest uznawana za niecodzienną,
    // jeśli znajduje się między godziną początkową i końcową.
    if (startTime < endTime) {
      return((currentTime >= startTime) &&
             (currentTime < endTime));
    }
    // Jeśli godzina początkowa jest większa lub równa
    // godzinie końcowej (czyli godzina początkowa należy do jednego dnia,
    // a godzina końcowa dotyczy już następnego dnia),
    // wówczas godzina bieżąca jest uznawana za niecodzienną,
    // jeśli NIE należy do przedziału między godziną końcową i początkową.
    else {
      return(!isUnusualTime(currentTime, endTime, startTime));
    }
  } 
}
