
//import it.inaf.ia2.aa.data.User;

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*; // ArrayList<String> Collection<>

import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;


import javax.servlet.http.HttpServletRequestWrapper;
import java.security.Principal;


/* response wrapper */

import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.ServletOutputStream;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.OutputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayOutputStream;



class AuthZ
{
   private static final Logger LOGGER = Logger.getLogger("AuthZ");
   private static final AuthZSettings settings = AuthZSettings.getInstance("authpolicy.properties");

   List<String> pubdidList = new ArrayList<String>();

   String servletPath;


   public AuthZ(HttpServletRequest req) throws IOException, ServletException
   {
      LOGGER.info("constructor");

      String[] pubdidArr = req.getParameterValues("ID");
      if(pubdidArr == null)
      {
         String pubdids = req.getParameter("pubdid");
         if(pubdids != null) pubdidArr = pubdids.split(";");
      }

      if(pubdidArr != null)
      {
         for(String pubdid : pubdidArr)
            if(pubdid.length() > 0) pubdidList.add(pubdid);

         LOGGER.info("pubdids: " + String.join(" ", pubdidList));
      }
   }


   private String getValue(Part part) throws IOException
   {
      BufferedReader reader = new BufferedReader(new InputStreamReader(part.getInputStream(), "UTF-8"));
      StringBuilder value = new StringBuilder();
      char[] buffer = new char[1024];
      for (int length = 0; (length = reader.read(buffer)) > 0;)
      {
         value.append(buffer, 0, length);
      }
      return value.toString();
   }



   public boolean isAuthorized(HttpServletRequest req)
   {
      LOGGER.info("isAuthorized");

      AuthPolicy auth = null;
      try
      {
         auth = new AuthPolicy(req.getUserPrincipal());
      }
      catch(IllegalArgumentException ex)
      {
         throw new IllegalArgumentException("Authorization : UserPrincipal is not of expected type");
      }
      String[] pubdidArr = pubdidList.toArray(new String[pubdidList.size()]);
      String[] authorized_pubdids;
      authorized_pubdids = auth.filterAuthorized(pubdidArr, settings.dbConn.uri(), settings.dbConn.userName(), settings.dbConn.password());

      /* If multiplicity allowed (and in mcutout/merge):
       * if one or more of pubdids not-authorized -> all request not authorized
       * */
      /* NOTE for now soda/vlkb_cutout does not allow multiplicity --> only one pubdid allowed */
      return (authorized_pubdids.length == pubdidArr.length);
   }

}





@javax.servlet.annotation.MultipartConfig
public class AuthZFilter implements Filter
{
   private static final Logger LOGGER = Logger.getLogger("AuthZFilter");


   @Override
   public void init(FilterConfig fc) throws ServletException {}

   @Override
   public void destroy() {}

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
   {
      LOGGER.info("doFilter");

      HttpServletRequest  req  = (HttpServletRequest)  request;
      HttpServletResponse  resp = (HttpServletResponse)  response;

      AuthZ authz = new AuthZ(req);

      if(authz.isAuthorized(req))
      {
         chain.doFilter(request, response);
      }
      else
      {
         resp.setContentType("text/plain");
         resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden");
      }
   }

}

