package ctbrec.servlet;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class StaticFileServlet extends HttpServlet {

    private String classPathRoot;
    private Map<String, String> mimetypes = new HashMap<>();
    private boolean contextAware = true;

    public StaticFileServlet(String classPathRoot) {
        this.classPathRoot = classPathRoot;
        mimetypes.put("css", "text/css");
        mimetypes.put("js", "application/javascript");
    }

    public StaticFileServlet(String classPathRoot, boolean contextAware) {
        this(classPathRoot);
        this.contextAware = contextAware;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String request = req.getRequestURI();
        if (contextAware) {
            String contextPath = getServletContext().getContextPath();
            request = request.substring(contextPath.length());
        }
        serveFile(request, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    private void serveFile(String resource, HttpServletResponse resp) throws IOException {
        InputStream resourceAsStream = getClass().getResourceAsStream(classPathRoot + resource);
        if (resourceAsStream == null) {
            throw new FileNotFoundException();
        }

        String mimetype = URLConnection.guessContentTypeFromName(resource);
        if (mimetype == null) {
            mimetype = guessMimeType(resource);
        }
        resp.setContentType(mimetype);
        resp.setStatus(HttpServletResponse.SC_OK);
        OutputStream out = resp.getOutputStream();
        int length = 0;
        byte[] buffer = new byte[1024];
        while ((length = resourceAsStream.read(buffer)) >= 0) {
            out.write(buffer, 0, length);
        }
    }

    private String guessMimeType(String resource) {
        try {
            String extension = resource.substring(resource.lastIndexOf('.') + 1);
            return mimetypes.get(extension);
        } catch(Exception e) {}
        return null;
    }
}
