package com.commafeed.frontend.rest;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;

import org.apache.commons.lang.time.DateUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

@Provider
@Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN })
@Consumes(MediaType.APPLICATION_JSON)
public class JSONMessageBodyReaderWriter implements MessageBodyWriter<Object>,
		MessageBodyReader<Object> {

	private static final String UTF_8 = "UTF-8";

	private Gson gson;

	@Override
	public boolean isWriteable(Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType) {
		return true;
	}

	@Override
	public boolean isReadable(Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType) {
		return true;
	}

	@Override
	public long getSize(Object t, Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType) {
		return -1;
	}

	@Override
	public void writeTo(Object t, Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType,
			MultivaluedMap<String, Object> httpHeaders,
			OutputStream entityStream) throws IOException,
			WebApplicationException {
		httpHeaders.putSingle(HttpHeaders.CONTENT_TYPE, mediaType.toString()
				+ ";charset=" + UTF_8);
		httpHeaders.putSingle(HttpHeaders.CACHE_CONTROL, "no-cache");
		httpHeaders.putSingle("Pragma", "no-cache");
		if (type == String.class) {
			entityStream.write(t.toString().getBytes(UTF_8));
		} else {
			OutputStreamWriter writer = new OutputStreamWriter(entityStream,
					UTF_8);
			getGson().toJson(t, type, writer);
			writer.flush();
		}
	}

	@Override
	public Object readFrom(Class<Object> type, Type genericType,
			Annotation[] annotations, MediaType mediaType,
			MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
			throws IOException, WebApplicationException {
		InputStreamReader reader = new InputStreamReader(
				new BufferedInputStream(entityStream), UTF_8);
		return getGson().fromJson(reader, type);
	}

	private Gson getGson() {
		if (gson == null) {
			gson = new GsonBuilder().registerTypeAdapter(Date.class,
					new DateSerializer()).create();
		}
		return gson;
	}

	private static class DateSerializer implements JsonSerializer<Date> {

		private static final String DAY_FORMAT = "yyyy-MM-dd";
		private static final String TIME_FORMAT = "HH:mm";

		public JsonElement serialize(Date src, Type typeOfSrc,
				JsonSerializationContext context) {
			Date now = Calendar.getInstance().getTime();
			String format = DateUtils.isSameDay(now, src) ? TIME_FORMAT
					: DAY_FORMAT;
			return new JsonPrimitive(new SimpleDateFormat(format).format(src));
		}
	}

}

@@ -389,16 +389,70 @@
 l.Date;%0D
+%0Aimport java.util.Locale;%0D%0Aimport java.util.TimeZone;%0D
 %0A%0D%0Aimpor
@@ -834,24 +834,73 @@
 teUtils;%0D%0A%0D%0A
+import com.commafeed.frontend.CommaFeedSession;%0D%0A
 import com.g
@@ -3595,64 +3595,310 @@
 T;%0D%0A
+%0D%0A
 %09%09%09
-return new JsonPrimitive(new SimpleDateFormat(format)
+Locale locale = CommaFeedSession.get().getLocale();%0D%0A%09%09%09Calendar calendar = Calendar.getInstance(locale);%0D%0A%09%09%09TimeZone timeZone = calendar.getTimeZone();%0D%0A%09%09%09SimpleDateFormat dateFormat = new SimpleDateFormat(format);%0D%0A%09%09%09dateFormat.setTimeZone(timeZone);%0D%0A%0D%0A%09%09%09return new JsonPrimitive(dateFormat
 .for

format date using client timezone