package be.ac.ulb.code.wit.resources;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;

import be.ac.ulb.code.wit.ServiceConfiguration;
import be.ac.ulb.code.wit.resources.serializers.helpers.UnauthorizedException;

import com.sun.jersey.api.NotFoundException;

@Path("static")
public class AppView {
	private static InputStream readFile(File path) throws IOException {
		return new FileInputStream(path);
	}

	public String getBasePath() {
		return ServiceConfiguration.VIEW_BASE.replaceFirst("~",
				System.getProperty("user.home"));
	}

	private boolean checkParentDir(File root, File target) {
		File check = target.getParentFile();
		while (check != null && !check.equals(root)) {
			check = check.getParentFile();
		}

		return check.equals(root);
	}

	private File getAppDir(String subdir) {
		File directory = new File(getBasePath(), subdir);

		if (!directory.exists()) {
			throw new RuntimeException("Unknown static directory: " + subdir);
		}
		return directory;
	}

	private File getAppFile(File directory, String file) {
		File target = new File(directory, file);

		if (!checkParentDir(directory, target)) {
			throw new UnauthorizedException();
		}

		if (!target.exists()) {
			throw new NotFoundException();
		}

		if (target.isDirectory()) {
			throw new UnauthorizedException();
		}

		return target;
	}

	private static Map<String, String> extMap = null;

	private String inferTypeFromExtension(File file) {
		if (extMap == null) {
			extMap = new HashMap<String, String>();
			extMap.put("js", "application/javascript");
			extMap.put("css", "text/css");
			extMap.put("png", "image/png");
			extMap.put("mustache", "text/x-mustache");
			extMap.put("html", "text/html");
		}

		String name = file.getName();
		int extstart = name.lastIndexOf('.');
		return extMap.get(name.substring(extstart + 1));
	}

	private Response getAppFile(String subdir, String file) {
		File target = getAppFile(getAppDir(subdir), file);
		String type = inferTypeFromExtension(target);

		try {
			if (type != null) {
				return Response.ok().type(type).entity(readFile(target))
						.build();
			}
			return Response.ok().entity(readFile(target)).build();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	@GET
	@Path("{path:.+}")
	public Response getApplicationView(@PathParam("path") String file) {
		// Read the main file
		return getAppFile(".", file);
	}
}
