package au.gov.amsa.detection;

import java.util.Date;

import javax.persistence.EntityManager;

import com.google.common.base.Optional;

import au.gov.amsa.detection.model.Context;
import au.gov.amsa.detection.model.Craft;
import au.gov.amsa.detection.model.CraftIdentifierType;

public class ApiEngine implements Api {

    @Override
    public void addCompositeRegion() {
        // TODO Auto-generated method stub

    }

    @Override
    public void modifyCompositeRegion() {
        // TODO Auto-generated method stub

    }

    @Override
    public void addMessageTemplate() {
        // TODO Auto-generated method stub

    }

    @Override
    public void modifyMessageTemplate() {
        // TODO Auto-generated method stub

    }

    @Override
    public void addMessageRecipient() {
        // TODO Auto-generated method stub

    }

    @Override
    public void modifyMessageRecipient() {
        // TODO Auto-generated method stub

    }

    @Override
    public void reportPosition(String craftIdentifierTypeName, String craftIdentifier,
            double latitude, double longitude, double altitudeMetres, long time) {
        Optional<Craft> craft = getCraft(craftIdentifierTypeName, craftIdentifier);
        Craft c;
        if (!craft.isPresent()) {
            try {
                c = Craft.create(Craft.Events.Create.builder().craftIdentifier(craftIdentifier)
                        .craftIdentifierTypeName("MMSI").build());
            } catch (RuntimeException e) {
                // if already exists then loading it again should not fail
                c = getCraft(craftIdentifierTypeName, craftIdentifier).get();
            }
        } else {
            c = craft.get();
        }
        c.signal(Craft.Events.Position.builder().altitudeMetres(0.0).latitude(latitude)
                .longitude(longitude).time(new Date(time)).currentTime(new Date(Clock.now()))
                .build());

    }

    private Optional<Craft> getCraft(String craftIdentifierTypeName, String craftIdentifier) {
        EntityManager em = Context.createEntityManager();
        try {
            CraftIdentifierType cit = CraftIdentifierType
                    .select(CraftIdentifierType.Attribute.name.eq(craftIdentifierTypeName)).one(em)
                    .get();
            return Craft.select(Craft.Attribute.craftIdentifierType_R20_id.eq(cit.getId())
                    .and(Craft.Attribute.identifier.eq(craftIdentifier))).any(em);
        } finally {
            em.close();
        }
    }

    @Override
    public long queueSize() {
        return Context.queueSize();
    }

    @Override
    public void clearQueue() {
        throw new RuntimeException("not implemented");
    }

    @Override
    public void createDetectionRule(String name, String description, long startTime, long endTime,
            int minIntervalSeconds, int minIntervalSecondsOutsideRegion, boolean mustCross,
            String craftIdentifierPattern, String regionId) {
        // TODO Auto-generated method stub

    }

    @Override
    public void updateDetectionRule(String name, String description, long startTime, long endTime,
            int minIntervalSeconds, int minIntervalSecondsOutsideRegion, boolean mustCross,
            String craftIdentifierPattern, String regionId) {
        // TODO Auto-generated method stub

    }

    @Override
    public void addSimpleRegion(String name, String description, String simpleRegionType,
            byte[] bytes) {
        // TODO Auto-generated method stub

    }

    @Override
    public void modifySimpleRegion(String name, String description, String simpleRegionType,
            byte[] bytes) {
        // TODO Auto-generated method stub

    }

}

@@ -129,16 +129,61 @@
 ptional;
+%0Aimport com.google.common.base.Preconditions;
 %0A%0Aimport
@@ -425,42 +425,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  
@@ -542,42 +542,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  
@@ -656,42 +656,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  
@@ -773,42 +773,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  
@@ -888,42 +888,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  
@@ -1006,42 +1006,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  
@@ -1235,24 +1235,274 @@
 ong time) %7B%0A
+        // don't need preconditions because all specified in data model%0A%0A        // just expect MMSI for the moment%0A        Preconditions.checkArgument(%22MMSI%22.equals(craftIdentifierTypeName),%0A                %22craftIdentifierTypeName must be MMSI%22);%0A%0A
         Opti
@@ -3349,42 +3349,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  
@@ -3677,42 +3677,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  
@@ -3870,42 +3870,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  
@@ -4066,42 +4066,52 @@
     
-// TODO Auto-generated method stub
+throw new RuntimeException(%22unimplemented%22);
 %0A%0A  

add precondition to API