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


import android.support.annotation.NonNull;

import org.hisp.dhis.android.core.common.LinkModelHandler;
import org.hisp.dhis.android.core.common.LinkModelHandlerImpl;
import org.hisp.dhis.android.core.data.database.DatabaseAdapter;

import java.util.List;

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

public class CategoryComboHandler {

    @NonNull
    private final LinkModelHandler<CategoryOption, CategoryOptionComboCategoryOptionLinkModel>
            categoryOptionComboCategoryOptionLinkHandler;

    @NonNull
    private final LinkModelHandler<Category, CategoryCategoryComboLinkModel> categoryCategoryComboLinkHandler;

    @NonNull
    private final CategoryOptionComboHandler optionComboHandler;

    @NonNull
    private final CategoryComboStore store;

    CategoryComboHandler(
            @NonNull CategoryComboStore store,
            @NonNull LinkModelHandler<CategoryOption, CategoryOptionComboCategoryOptionLinkModel>
                    categoryOptionComboCategoryOptionLinkHandler,
            @NonNull LinkModelHandler<Category, CategoryCategoryComboLinkModel> categoryCategoryComboLinkHandler,
            @NonNull CategoryOptionComboHandler optionComboHandler) {
        this.store = store;
        this.categoryOptionComboCategoryOptionLinkHandler = categoryOptionComboCategoryOptionLinkHandler;
        this.categoryCategoryComboLinkHandler = categoryCategoryComboLinkHandler;
        this.optionComboHandler = optionComboHandler;
    }

    public void handle(CategoryCombo combo) {

        if (isDeleted(combo)) {
            store.delete(combo);
        } else {

            boolean updated = store.update(combo, combo);

            if (!updated) {
                store.insert(combo);
            }

            handleRelations(combo);
        }
    }

    private void handleRelations(@NonNull CategoryCombo combo) {
        categoryCategoryComboLinkHandler.handleMany(combo.uid(), combo.categories(),
                new CategoryCategoryComboLinkModelBuilder(combo));

        handleOptionCombo(combo);
    }

    @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
    private void handleOptionCombo(@NonNull CategoryCombo combo) {
        List<CategoryOptionCombo> optionsCombo = combo.categoryOptionCombos();

        if (optionsCombo != null) {
            for (CategoryOptionCombo optionCombo : optionsCombo) {
                optionComboHandler.handle(optionCombo);
                categoryOptionComboCategoryOptionLinkHandler.handleMany(optionCombo.uid(),
                        optionCombo.categoryOptions(),
                        new CategoryOptionComboCategoryOptionLinkModelBuilder(optionCombo));
            }
        }
    }

    public static CategoryComboHandler create(DatabaseAdapter databaseAdapter) {
        return new CategoryComboHandler(
                new CategoryComboStoreImpl(databaseAdapter),
                new LinkModelHandlerImpl<CategoryOption, CategoryOptionComboCategoryOptionLinkModel>(
                        CategoryOptionComboCategoryOptionLinkStore.create(databaseAdapter)
                ),
                new LinkModelHandlerImpl<Category, CategoryCategoryComboLinkModel>(
                        CategoryCategoryComboLinkStore.create(databaseAdapter)
                ),
                CategoryOptionComboHandler.create(databaseAdapter)
        );
    }
}

@@ -84,16 +84,71 @@
 nNull;%0A%0A
+import org.hisp.dhis.android.core.common.HandleAction;%0A
 import o
@@ -261,16 +261,132 @@
 erImpl;%0A
+import org.hisp.dhis.android.core.common.OrphanCleaner;%0Aimport org.hisp.dhis.android.core.common.OrphanCleanerImpl;%0A
 import o
@@ -996,16 +996,107 @@
 e store;
+%0A    private final OrphanCleaner%3CCategoryCombo, CategoryOptionCombo%3E categoryOptionCleaner;
 %0A%0A    Ca
@@ -1506,16 +1506,101 @@
 oHandler
+,%0A            OrphanCleaner%3CCategoryCombo, CategoryOptionCombo%3E categoryOptionCleaner
 ) %7B%0A    
@@ -1861,24 +1861,84 @@
 mboHandler;%0A
+        this.categoryOptionCleaner = categoryOptionCleaner;%0A
     %7D%0A%0A    p
@@ -1978,17 +1978,16 @@
 ombo) %7B%0A
-%0A
         
@@ -2060,17 +2060,16 @@
  else %7B%0A
-%0A
         
@@ -2117,16 +2117,71 @@
  combo);
+%0A            HandleAction action = HandleAction.Update;
 %0A%0A      
@@ -2231,32 +2231,78 @@
 .insert(combo);%0A
+                action = HandleAction.Insert;%0A
             %7D%0A%0A 
@@ -2327,32 +2327,185 @@
 elations(combo);
+%0A%0A            if (action == HandleAction.Update) %7B%0A                categoryOptionCleaner.deleteOrphan(combo, combo.categoryOptionCombos());%0A            %7D
 %0A        %7D%0A    %7D
@@ -4038,32 +4038,229 @@
 databaseAdapter)
+,%0A                new OrphanCleanerImpl%3CCategoryCombo, CategoryOptionCombo%3E(CategoryOptionComboModel.TABLE,%0A                        CategoryOptionComboModel.Columns.CATEGORY_COMBO, databaseAdapter)
 %0A        );%0A    
@@ -4262,9 +4262,8 @@
 %0A    %7D%0A%7D
-%0A

clean categoryOptionCombo orphans