/*
 * Copyright 2011 Jonathan Anderson
 *
 * 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 me.footlights.ui.web;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
import java.util.regex.Pattern;

import com.google.common.collect.Maps;

import me.footlights.core.plugin.PluginWrapper;
import me.footlights.plugin.WebRequest;


/** Code to serve static plugin content. */
class StaticContentServer implements WebServer
{
	StaticContentServer(Map<String,PluginWrapper> plugins)
	{
		paths = Maps.newHashMap();

		for (Map.Entry<String,PluginWrapper> plugin : plugins.entrySet())
			paths.put(plugin.getKey(), plugin.getValue().getClass());

		paths.put("footlights", getClass());

		// TODO: this is a temporary cheat for testing.
		paths.put("sandbox", getClass());
	}

	@Override public String name() { return "static content server"; }

	@Override public Response handle(final WebRequest request)
		throws FileNotFoundException, IOException, SecurityException
	{
		if (request.path().contains(".."))
			throw new SecurityException("'..' present in " + request);

		if (request.path().isEmpty())
			return Response.newBuilder()
				.setResponse(
						mimeType("index.html"),
						this.getClass().getResource("index.html").openStream())
				.build();

		Class<?> c = paths.get(request.prefix());
		if (c == null)
			throw new FileNotFoundException("No such directory '" + request.prefix() + "'");

		String path = request.shift().path();
		URL resource = c.getResource(request.shift().path());
		if (resource == null) throw new FileNotFoundException(path);

		java.io.File file = new java.io.File(resource.getFile());
		if (!file.isFile()) throw new FileNotFoundException(path);

		InputStream data = resource.openStream();
		if (data == null) throw new FileNotFoundException(path);

		return Response.newBuilder()
			.setResponse(mimeType(path), data)
			.build();
	}

	/** Guess the MIME type for static content. */
	private String mimeType(String path)
	{
		if (Pattern.matches(".*\\.css", path))
			return "text/css";

		else if (Pattern.matches(".*\\.gif", path))
			return "image/gif";

		else if (Pattern.matches(".*\\.html", path))
			return "text/html";

		else if (Pattern.matches(".*\\.jpe?g", path))
			return "image/jpeg";

		else if (Pattern.matches(".*\\.js", path))
			return "text/javascript";

		else if (Pattern.matches(".*\\.png", path))
			return "image/png";

		return "text/xml";
	}

	private final Map<String,Class<?>> paths;
}

@@ -1105,16 +1105,42 @@
 shMap();
+%0A%09%09this.plugins = plugins;
 %0A%0A%09%09for 
@@ -1267,48 +1267,8 @@
 );%0A%0A
-%09%09paths.put(%22footlights%22, getClass());%0A%0A
 %09%09//
@@ -1456,22 +1456,16 @@
  handle(
-final 
 WebReque
@@ -1833,16 +1833,22 @@
 d();%0A%0A%09%09
+final 
 Class%3C?%3E
@@ -1852,16 +1852,131 @@
 %3C?%3E 
-c = path
+resourceLoader;%0A%09%09if (request.prefix().equals(%22plugin%22))%0A%09%09%7B%0A%09%09%09request = request.shift();%0A%09%09%09PluginWrapper plugin = plugin
 s.ge
@@ -2002,13 +2002,19 @@
 ;%0A%09%09
+%09
 if (
-c
+plugin
  == 
@@ -2019,16 +2019,17 @@
 = null)%0A
+%09
 %09%09%09throw
@@ -2068,19 +2068,15 @@
 uch 
-directory '
+plugin 
 %22 + 
@@ -2095,114 +2095,166 @@
 ix()
- + %22'%22);%0A%0A%09%09String path = request.shift().path();%0A%09%09URL resource = c.getResource(request.shift().path
+);%0A%0A%09%09%09resourceLoader = plugin.getWrappedPlugin().getClass();%0A%09%09%7D%0A%09%09else if (request.prefix().equals(%22footlights%22))%0A%09%09%7B%0A%09%09%09resourceLoader = this.getClass
 ()
-)
 ;%0A
+%09
 %09%09if
@@ -2263,16 +2263,22 @@
 resource
+Loader
  == null
@@ -2270,33 +2270,37 @@
 eLoader == null)
- 
+%0A%09%09%09%09
 throw new FileNo
@@ -2319,96 +2319,284 @@
 ion(
-path);%0A%0A%09%09java.io.File file = new java.io.File(resource.getFile());%0A%09%09if (!file.isFile()
+%22No such directory '%22 + request.prefix() + %22'%22);%0A%09%09%7D%0A%09%09else throw new FileNotFoundException(%0A%09%09%09%22Static content filename must start with either 'footlights' or 'plugin'%22);%0A%0A%09%09String path = request.shift().path();%0A%09%09URL url = resourceLoader.getResource(path);%0A%09%09if (url == null
 ) th
@@ -2654,24 +2654,19 @@
  data = 
-resource
+url
 .openStr
@@ -3398,10 +3398,61 @@
  paths;%0A
+%09private final Map%3CString, PluginWrapper%3E plugins;%0A
 %7D%0A

Handle static plugin content properly.