package org.hisp.dhis.android.core.trackedentity;

import android.support.annotation.NonNull;

import org.hisp.dhis.android.core.common.State;
import org.hisp.dhis.android.core.data.database.DatabaseAdapter;
import org.hisp.dhis.android.core.enrollment.Enrollment;
import org.hisp.dhis.android.core.enrollment.EnrollmentHandler;

import java.util.List;

import static org.hisp.dhis.android.core.utils.Utils.isDeleted;

public class TrackedEntityInstanceHandler {
    private final TrackedEntityInstanceStore trackedEntityInstanceStore;
    private final TrackedEntityAttributeValueHandler trackedEntityAttributeValueHandler;
    private final EnrollmentHandler enrollmentHandler;


    public TrackedEntityInstanceHandler(
            @NonNull TrackedEntityInstanceStore trackedEntityInstanceStore,
            @NonNull TrackedEntityAttributeValueHandler trackedEntityAttributeValueHandler,
            @NonNull EnrollmentHandler enrollmentHandler) {
        this.trackedEntityInstanceStore = trackedEntityInstanceStore;
        this.trackedEntityAttributeValueHandler = trackedEntityAttributeValueHandler;
        this.enrollmentHandler = enrollmentHandler;
    }

    public void handle(@NonNull TrackedEntityInstance trackedEntityInstance) {
        if (trackedEntityInstance == null) {
            return;
        }

        if (isDeleted(trackedEntityInstance)) {
            trackedEntityInstanceStore.delete(trackedEntityInstance.uid());
        } else {
            int updatedRow = trackedEntityInstanceStore.update(
                    trackedEntityInstance.uid(), trackedEntityInstance.created(), trackedEntityInstance.lastUpdated(),
                    trackedEntityInstance.createdAtClient(), trackedEntityInstance.lastUpdatedAtClient(),
                    trackedEntityInstance.organisationUnit(), trackedEntityInstance.trackedEntityType(),
                    trackedEntityInstance.coordinates(), trackedEntityInstance.featureType(),
                    State.SYNCED, trackedEntityInstance.uid());

            if (updatedRow <= 0) {
                trackedEntityInstanceStore.insert(
                        trackedEntityInstance.uid(), trackedEntityInstance.created(),
                        trackedEntityInstance.lastUpdated(), trackedEntityInstance.createdAtClient(),
                        trackedEntityInstance.lastUpdatedAtClient(), trackedEntityInstance.organisationUnit(),
                        trackedEntityInstance.trackedEntityType(), trackedEntityInstance.coordinates(),
                        trackedEntityInstance.featureType(), State.SYNCED);
            }

            trackedEntityAttributeValueHandler.handle(
                    trackedEntityInstance.uid(),
                    trackedEntityInstance.trackedEntityAttributeValues());

            List<Enrollment> enrollments = trackedEntityInstance.enrollments();

            enrollmentHandler.handle(enrollments);
        }
    }

    public static TrackedEntityInstanceHandler create(DatabaseAdapter databaseAdapter) {
        return new TrackedEntityInstanceHandler(
                new TrackedEntityInstanceStoreImpl(databaseAdapter),
                TrackedEntityAttributeValueHandler.create(databaseAdapter),
                EnrollmentHandler.create(databaseAdapter)
        );
    }
}

@@ -321,16 +321,213 @@
 Handler;
+%0Aimport org.hisp.dhis.android.core.relationship.Relationship;%0Aimport org.hisp.dhis.android.core.relationship.RelationshipStore;%0Aimport org.hisp.dhis.android.core.relationship.RelationshipStoreImpl;
 %0A%0Aimport
@@ -722,24 +722,79 @@
 tanceStore;%0A
+    private final RelationshipStore relationshipStore;%0A
     private 
@@ -926,17 +926,16 @@
 ndler;%0A%0A
-%0A
     publ
@@ -1043,16 +1043,74 @@
 eStore,%0A
+            @NonNull RelationshipStore relationshipStore,%0A
         
@@ -1249,24 +1249,24 @@
 tHandler) %7B%0A
-
         this
@@ -1319,24 +1319,76 @@
 tanceStore;%0A
+        this.relationshipStore = relationshipStore;%0A
         this
@@ -3260,16 +3260,398 @@
 lments);
+%0A%0A            for (Relationship relationship : trackedEntityInstance.relationships()) %7B%0A                this.handle(relationship.relative());%0A                this.relationshipStore.insert(%0A                        relationship.trackedEntityInstanceA(),%0A                        relationship.trackedEntityInstanceB(),%0A                        relationship.relationship());%0A            %7D
 %0A       
@@ -3859,32 +3859,92 @@
 tabaseAdapter),%0A
+                new RelationshipStoreImpl(databaseAdapter),%0A
                 

store relationships