/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.usergrid.rest;


import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;

import com.sun.jersey.api.json.JSONWithPadding;
import com.sun.jersey.spi.MessageBodyWorkers;


/**
 * A writer that will redirect requests for "text/html" to "application/json" if the value
 * returned by the resource is an instance of JSONWithPadding
 *
 * @author tnine
 *
 */
@Provider
@Produces( MediaType.TEXT_HTML )
public class TextToJsonSwapWriter implements MessageBodyWriter<JSONWithPadding> {


    private static final MediaType JSON_MEDIA_TYPE = MediaType.APPLICATION_JSON_TYPE;

    @Context
    MessageBodyWorkers bodyWorker;


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

        //this should only map no media type, or text/html requests with json responses

        final boolean mediaTypeCorrect = mediaType == null || MediaType.TEXT_HTML_TYPE.equals( mediaType );

        if(!mediaTypeCorrect){
            return false;
        }

        return true;

// JsonSerializableWithType no longer exists in FasterXML Jackson
//
//        final boolean serializableAnnotation = type.getAnnotation( XmlRootElement.class ) != null;
//        final boolean jsonSerializable = JsonSerializableWithType.class.isAssignableFrom( type );
//        return serializableAnnotation || jsonSerializable;
    }


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


    @Override
    public void writeTo( final JSONWithPadding jsonWithPadding, final Class<?> type, final Type genericType,
                         final Annotation[] annotations, final MediaType mediaType,
                         final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream )
            throws IOException, WebApplicationException {


        Object jsonEntity = jsonWithPadding.getJsonSource();
        Type entityGenericType = jsonEntity.getClass();
        Class<?> entityType = jsonEntity.getClass();

        final boolean genericEntityUsed = jsonEntity instanceof GenericEntity;

        if ( genericEntityUsed ) {
            GenericEntity ge = ( GenericEntity ) jsonEntity;
            jsonEntity = ge.getEntity();
            entityGenericType = ge.getType();
            entityType = ge.getRawType();
        }


        //replace the text/html content type with application Json
        httpHeaders.remove( HttpHeaders.CONTENT_TYPE);

        httpHeaders.putSingle( HttpHeaders.CONTENT_TYPE,  JSON_MEDIA_TYPE);




        MessageBodyWriter bw = bodyWorker.getMessageBodyWriter( entityType, entityGenericType, annotations, JSON_MEDIA_TYPE );

        if ( bw == null ) {

            throw new RuntimeException( "Couldn't find the serailziation writer for json type");
        }




        bw.writeTo( jsonEntity, entityType, entityGenericType, annotations, JSON_MEDIA_TYPE, httpHeaders,
                entityStream );


    }
}

@@ -1342,16 +1342,57 @@
 adding;%0A
+import com.sun.jersey.api.view.Viewable;%0A
 import c
@@ -2061,24 +2061,25 @@
 iaType ) %7B%0A%0A
+%0A
         //th
@@ -2076,16 +2076,187 @@
       //
+ if type is Viewable them we want to return HTML, so no swap needed%0A        if ( type.isAssignableFrom(Viewable.class) ) %7B%0A            return false;%0A        %7D%0A%0A        // 
 this sho
@@ -2325,17 +2325,16 @@
 sponses%0A
-%0A
         

Fix JSP processing in the two-dot-o branch (USERGRID-209)