/*
 *  Copyright (C) 2015 Stichting Akvo (Akvo Foundation)
 *
 *  This file is part of Akvo FLOW.
 *
 *  Akvo FLOW is free software: you can redistribute it and modify it under the terms of
 *  the GNU Affero General Public License (AGPL) as published by the Free Software Foundation,
 *  either version 3 of the License or any later version.
 *
 *  Akvo FLOW is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU Affero General Public License included below for more details.
 *
 *  The full license text can also be seen at <http://www.gnu.org/licenses/agpl.html>.
 */

package org.akvo.gae.remoteapi;

import java.util.LinkedList;
import java.util.List;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Query;

public class CorrectFolderSurveyPath implements Process {

    private final String SURVEY_GROUP = "SurveyGroup";
    private final String SURVEY = "Survey";

    @Override
    public void execute(DatastoreService ds, String[] args) throws Exception {

        System.out.println("Fetching survey groups and surveys.");

        final List<Entity> surveyGroups = ds.prepare(new Query(SURVEY_GROUP)).asList(
                FetchOptions.Builder.withDefaults());
        final List<Entity> surveys = ds.prepare(new Query(SURVEY)).asList(
                FetchOptions.Builder.withDefaults());

        // combine entities to one list
        LinkedList<Entity> completeList = new LinkedList<Entity>();
        completeList.addAll(surveyGroups);
        completeList.addAll(surveys);

        for (Entity rootLevelEntity : completeList) {
            if (rootLevelEntity.getKind().equals(SURVEY_GROUP)
                    && rootLevelEntity.getProperty("parentId") == null) {
                updateFolderSurveyPaths(rootLevelEntity, "", completeList);
            }
        }

        System.out.println("Saving " + surveyGroups.size() + " survey groups; " + surveys.size()
                + " surveys.");
        ds.put(completeList);
    }

    private void updateFolderSurveyPaths(Entity entity, String pathPrefix, List<Entity> entities) {
        // set folder/survey path
        String entityPath = String.format("%s/%s", pathPrefix, entity.getProperty("name"));
        entity.setProperty("path", entityPath);
        System.out.println("Setting path for: " + entity.getKey() + " = " + entityPath);

        // set all child folders/surveys paths
        for (Entity childEntity : entities) {
            Long parentId = getParentId(childEntity);
            if (parentId != null && parentId.equals(entity.getKey().getId())) {
                updateFolderSurveyPaths(childEntity, entityPath, entities);
            }
        }
    }

    private Long getParentId(Entity childEntity) {
        if (childEntity.getKind().equals(SURVEY_GROUP)) {
            return (Long) childEntity.getProperty("parentId");
        } else {
            return (Long) childEntity.getProperty("surveyGroupId");
        }
    }
}

@@ -731,16 +731,44 @@
 teapi;%0A%0A
+import java.util.ArrayList;%0A
 import j
@@ -1091,32 +1091,39 @@
  %7B%0A%0A    private 
+static 
 final String SUR
@@ -1161,16 +1161,23 @@
 private 
+static 
 final St
@@ -1199,16 +1199,84 @@
 Survey%22;
+%0A    private List%3CEntity%3E updatedEntities = new ArrayList%3CEntity%3E();
 %0A%0A    @O
@@ -2195,156 +2195,30 @@
     
-System.out.println(%22Saving %22 + surveyGroups.size() + %22 survey groups; %22 + surveys.size()%0A                + %22 surveys.%22);%0A        ds.put(completeList
+ds.put(updatedEntities
 );%0A 
@@ -2372,17 +2372,86 @@
  String 
-e
+currentPath = (String) entity.getProperty(%22path%22);%0A        String newE
 ntityPat
@@ -2514,24 +2514,191 @@
 y(%22name%22));%0A
+        if (newEntityPath.equals(currentPath)) %7B%0A            System.out.println(%22No changes made for: %22 + entity.getKey() + %22 = %22 + currentPath);%0A        %7D else %7B%0A    
         enti
@@ -2720,17 +2720,20 @@
 %22path%22, 
-e
+newE
 ntityPat
@@ -2732,24 +2732,69 @@
 ntityPath);%0A
+            updatedEntities.add(entity);%0A    
         Syst
@@ -2852,18 +2852,63 @@
 () +
+ %22; %22 + currentPath +
  %22 =
+%3E
  %22
- + e
+%0A                    + newE
 ntit
@@ -2914,16 +2914,26 @@
 tyPath);
+%0A        %7D
 %0A%0A      
@@ -3206,17 +3206,20 @@
 Entity, 
-e
+newE
 ntityPat

Update only incorrect path entities