/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.dubbo.container.page;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

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 com.alibaba.dubbo.common.Constants;

/**
 * ResourceServlet
 * 
 * @author william.liangf
 */
public class ResourceFilter implements Filter {

    private static final String CLASSPATH_PREFIX = "classpath:";

    private final long start = System.currentTimeMillis();

    private final List<String> resources = new ArrayList<String>();

    public void init(FilterConfig filterConfig) throws ServletException {
        String config = filterConfig.getInitParameter("resources");
        if (config != null && config.length() > 0) {
            String[] configs = Constants.COMMA_SPLIT_PATTERN.split(config);
            for (String c : configs) {
                if (c != null && c.length() > 0) {
                    c = c.replace('\\', '/');
                    if (c.endsWith("/")) {
                        c = c.substring(0, c.length() - 1);
                    }
                    resources.add(c);
                }
            }
        }
    }

    public void destroy() {
    }
    
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        if (response.isCommitted()) {
            return;
        }
        String uri = request.getRequestURI();
        String context = request.getContextPath();
        if (uri.endsWith("/favicon.ico")) {
            uri = "/favicon.ico";
        } else if (context != null && ! "/".equals(context)) {
            uri = uri.substring(context.length());
        }
        if (! uri.startsWith("/")) {
            uri = "/" + uri;
        }
        long lastModified = getLastModified(uri);
        long since = request.getDateHeader("If-Modified-Since");
        if (since >= lastModified) {
        	response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
        	return;
        }
        byte[] data;
        InputStream input = getInputStream(uri);
    	if (input == null) {
    	    chain.doFilter(req, res);
            return;
        }
    	try {
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[8192];
            int n = 0;
            while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
            }
            data = output.toByteArray();
        } finally {
            input.close();
        }
        response.setDateHeader("Last-Modified", lastModified);
        OutputStream output = response.getOutputStream();
        output.write(data);
        output.flush();
    }
    
    private boolean isFile(String path) {
        return path.startsWith("/") || path.indexOf(":") <= 1;
    }
	
	private long getLastModified(String uri) {
	    for (String resource : resources) {
            if (resource != null && resource.length() > 0) {
                String path = resource + uri;
                if (isFile(path)) {
                    File file = new File(path);
                    if (file.exists()) {
                        return file.lastModified();
                    }
                }
            }
        }
        return start;
	}
	
	private InputStream getInputStream(String uri) {
        for (String resource : resources) {
            String path = resource + uri;
            try {
                if (isFile(path)) {
                    return new FileInputStream(path);
                } else if (path.startsWith(CLASSPATH_PREFIX)) {
                    return Thread.currentThread().getContextClassLoader().getResourceAsStream(path.substring(CLASSPATH_PREFIX.length()));
                } else {
                    return new URL(path).openStream();
                }
            } catch (IOException e) {
            }
        }
        return null;
	}

}