package fgis.server.services;

import fgis.server.entity.fgis.Resource;
import fgis.server.entity.fgis.ResourceTrack;
import fgis.server.entity.fgis.dao.ResourceRepository;
import fgis.server.entity.fgis.dao.ResourceTrackRepository;
import java.io.StringWriter;
import java.util.Calendar;
import java.util.List;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonGeneratorFactory;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.glassfish.json.JsonGeneratorFactoryImpl;

@SuppressWarnings({ "UnusedDeclaration", "JavaDoc" })
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Startup
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@Path("/resource")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
public class ResourceService
{
  @EJB
  private ResourceRepository _resourceService;

  @EJB
  private ResourceTrackRepository _resourceTrackService;

  @GET
  @Path("/{id}")
  @Produces({ MediaType.APPLICATION_JSON })
  public String getResource( final @PathParam("id") int resourceID )
  {
    final Resource resource = _resourceService.findByID( resourceID );
    if ( null == resource )
    {
      throw new WebApplicationException( ResponseUtil.entityNotFoundResponse() );
    }

    final List<ResourceTrack> tracks = getResourceTracks( resourceID );

    return toGeoJson( resource, tracks );
  }

  private List<ResourceTrack> getResourceTracks( final int resourceID )
  {
    final Calendar calendar = Calendar.getInstance();
    calendar.roll( Calendar.MINUTE, -1 );
    return _resourceTrackService.findAllByResourceSince( resourceID, calendar.getTime() );
  }

  private String toGeoJson( final Resource resource, final List<ResourceTrack> tracks )
  {
    final JsonGeneratorFactory factory = new JsonGeneratorFactoryImpl();
    final StringWriter writer = new StringWriter();
    final JsonGenerator generator = factory.createGenerator( writer );

    generator.writeStartObject().
      write( "title", resource.getName() ).
      write( "description", resource.getName() ).
      writeStartObject( "geo" ).
        write( "type", "FeatureCollection" ).
        writeStartArray( "features" ).
          writeStartObject().
            write( "type", "Feature" ).
            writeStartObject( "properties" ).
              write( "type", resource.getName() + "'s Trail" ).
              write( "description", resource.getName() + "'s Trail" ).
              write( "color", "blue" ).
              write( "date_created", "Sat Dec 01 2012 17:49:08 GMT+1100 (EST)" ). // tracks.get( 0 ).getCollectedAt()
            writeEnd().
            writeStartObject( "geometry" ).
              write( "type", "LineString" ).
              writeStartArray( "coordinates" );

    for ( final ResourceTrack track : tracks )
    {
      generator.writeStartArray().write( track.getLocation().getX() ).write( track.getLocation().getY() ).writeEnd();
    }

    generator.
              writeEnd().
            writeEnd().
            writeStartObject( "crs" ).
              write( "type", "name" ).
              writeStartObject( "properties" ).
                write( "name", "urn:ogc:def:crs:OGC:1.3:CRS84" ).
              writeEnd().
            writeEnd().
          writeEnd().
        writeEnd().
      writeEnd().
    writeEnd().
    close();

    return writer.toString();
  }
}

@@ -237,28 +237,101 @@
 ort 
-java.io.StringWriter
+fgis.server.support.FieldFilter;%0Aimport java.io.StringWriter;%0Aimport java.text.ParseException
 ;%0Aim
@@ -378,16 +378,50 @@
 l.List;%0A
+import javax.annotation.Nullable;%0A
 import j
@@ -874,24 +874,99 @@
 s.Produces;%0A
+import javax.ws.rs.QueryParam;%0Aimport javax.ws.rs.WebApplicationException;%0A
 import javax
@@ -1577,22 +1577,16 @@
 esource(
- final
  @PathPa
@@ -1594,16 +1594,22 @@
 am(%22id%22)
+ final
  int res
@@ -1607,34 +1607,144 @@
 l int resourceID
- )
+,%0A                             @QueryParam( %22fields%22 ) @Nullable final String fields )%0A    throws ParseException
 %0A  %7B%0A    final R
@@ -1995,24 +1995,85 @@
 ourceID );%0A%0A
+    final FieldFilter filter = FieldFilter.parse( fields );%0A%0A
     return t
@@ -2081,16 +2081,24 @@
 GeoJson(
+ filter,
  resourc
@@ -2421,26 +2421,108 @@
 nal 
-Resource resource,
+FieldFilter filter,%0A                            final Resource resource,%0A                           
  fin
@@ -2707,24 +2707,16 @@
 erator g
-enerator
  = facto
@@ -2747,32 +2747,24 @@
 er );%0A%0A    g
-enerator
 .writeStartO
@@ -2770,24 +2770,67 @@
 Object()
-.%0A 
+;%0A%0A    if( filter.allow( %22title%22 ) )%0A    %7B%0A
      
+ g.
 write( %22
@@ -2853,32 +2853,87 @@
 .getName() )
-.
+;%0A    %7D%0A%0A    if( filter.allow( %22description%22 ) )%0A    %7B
 %0A      
+g.
 write( %22desc
@@ -2962,24 +2962,71 @@
 Name() )
-.
+;%0A    %7D%0A%0A    if( filter.allow( %22geo%22 ) )%0A    %7B
 %0A      
+g.
 writeSta
@@ -3704,16 +3704,18 @@
 );%0A%0A    
+  
 for ( fi
@@ -3753,24 +3753,26 @@
 s )%0A    
+  
 %7B%0A      
 generato
@@ -3763,25 +3763,19 @@
 %7B%0A      
-generator
+  g
 .writeSt
@@ -3877,24 +3877,20 @@
     
+  
 %7D%0A%0A    
-generator
+  g
 .%0A  
@@ -4237,22 +4237,30 @@
 iteEnd()
-.
+;%0A    %7D
 %0A    
+g.
 writeEnd
@@ -4262,21 +4262,16 @@
 teEnd().
-%0A    
 close();

Support field filtering