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

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

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.HttpServletRequestWrapper;
import java.security.Principal;


public class IA2TokenConvFilter implements Filter
{
  private static final Logger LOGGER = Logger.getLogger(IA2TokenConvFilter.class.getName());

   @Override
   public void init(FilterConfig fc) throws ServletException
   {
      LOGGER.fine("trace");
   }

   @Override
   public void destroy()
   {
      LOGGER.fine("trace");
   }

   @Override
   public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                   throws IOException, ServletException
   {
      LOGGER.fine("trace");

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

        String authHeader = request.getHeader("Authorization");
        if (authHeader != null)
        {
            LOGGER.finer("Authorization header: " + authHeader.substring(0, 7+60) + " ...");
            if (authHeader.startsWith("Bearer "))
            {


               Principal principal = request.getUserPrincipal();
               if(principal == null)
               {
                   LOGGER.warning("User principal is null");
                   response.sendError(500, "Internal error - User principal is not correct");
                   return;
               }

               VlkbUser user = new VlkbUser();

               if(principal instanceof it.inaf.ia2.aa.data.User)
               {
                  it.inaf.ia2.aa.data.User alUser = (it.inaf.ia2.aa.data.User) principal;

                  String userId       = alUser.getName();//UserId
                  String userLabel    = alUser.getUserLabel();
                  List<String> groups = alUser.getGroups();

                  // FIXME check is any NULL ?

                  user.setUserId(userId);
                  user.setUserLabel(userLabel);
                  user.setGroups(groups);
               }
               else
               {
                   LOGGER.warning("User principal is incorrect type");
                   response.sendError(500, "Internal error - User principal is not correct type");
                   return;
               }

               HttpServletRequestWrapper requestWithPrincipal
                             = new RequestWithPrincipal(request, user);

               chain.doFilter(requestWithPrincipal, response);
               return;
            }
            else
            {
                LOGGER.warning("Detected Authorization header without Bearer token.");
            }
        }
        else
        {
            LOGGER.warning("Request has no Authorization header.");
            if(request.getUserPrincipal() != null)
            {
                   LOGGER.warning("User principal is set however no Authorization header present");
            //       response.sendError(500, "Internal error - It is not expected that Principal set in request but there is no Auhtprozation in HTTP-Header"); // FIXME use other err code not 500 here
             //      return;
            }
        }
        chain.doFilter(request, response);
//         response.sendError(401, "Unauthorized");
   }



   private static class RequestWithPrincipal extends HttpServletRequestWrapper
   {
      private final VlkbUser user;

         public RequestWithPrincipal(HttpServletRequest request, VlkbUser user)
               {   
                        super(request);
                              this.user = user;
                                 }   

            @Override
               public Principal getUserPrincipal() {
                        return user;
                           }   
   }

}

