/*
 * Copyright (c) 2017, University of Oslo
 *
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the name of the HISP project nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.hisp.dhis.android.core.program;

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 ProgramRuleVariableHandler {
    private final ProgramRuleVariableStore programRuleVariableStore;

    ProgramRuleVariableHandler(ProgramRuleVariableStore programRuleVariableStore) {
        this.programRuleVariableStore = programRuleVariableStore;
    }

    public void handleProgramRuleVariables(List<ProgramRuleVariable> programRuleVariables) {
        if (programRuleVariables == null) {
            return;
        }

        deleteOrPersistProgramRuleVariables(programRuleVariables);
    }

    private void deleteOrPersistProgramRuleVariables(List<ProgramRuleVariable> programRuleVariables) {
        int size = programRuleVariables.size();

        for (int i = 0; i < size; i++) {
            ProgramRuleVariable programRuleVariable = programRuleVariables.get(i);

            if (isDeleted(programRuleVariable)) {
                programRuleVariableStore.delete(programRuleVariable.uid());
            } else {
                String programStageUid = null;
                if(programRuleVariable.programStage() != null) {
                    programStageUid = programRuleVariable.programStage().uid();
                }

                String dataElementUid = null;
                if(programRuleVariable.dataElement() != null) {
                    dataElementUid = programRuleVariable.dataElement().uid();
                }

                String trackedEntityAttributeUid = null;
                if(programRuleVariable.trackedEntityAttribute() != null) {
                    trackedEntityAttributeUid = programRuleVariable.trackedEntityAttribute().uid();
                }

                int updatedRow = programRuleVariableStore.update(
                        programRuleVariable.uid(), programRuleVariable.code(),
                        programRuleVariable.name(), programRuleVariable.displayName(),
                        programRuleVariable.created(), programRuleVariable.lastUpdated(),
                        programRuleVariable.useCodeForOptionSet(),
                        programRuleVariable.program().uid(), programStageUid,
                        dataElementUid,
                        trackedEntityAttributeUid,
                        programRuleVariable.programRuleVariableSourceType(), programRuleVariable.uid()
                );

                if (updatedRow <= 0) {
                    programRuleVariableStore.insert(
                            programRuleVariable.uid(), programRuleVariable.code(),
                            programRuleVariable.name(), programRuleVariable.displayName(),
                            programRuleVariable.created(), programRuleVariable.lastUpdated(),
                            programRuleVariable.useCodeForOptionSet(),
                            programRuleVariable.program().uid(), programStageUid,
                            dataElementUid,
                            trackedEntityAttributeUid,
                            programRuleVariable.programRuleVariableSourceType()
                    );
                }
            }

        }
    }

    public static ProgramRuleVariableHandler create(DatabaseAdapter databaseAdapter) {
        return new ProgramRuleVariableHandler(new ProgramRuleVariableStoreImpl(databaseAdapter));
    }
}

@@ -1628,3171 +1628,427 @@
 ore.
-data.database.DatabaseAdapter;%0A%0Aimport java.util.List;%0A%0Aimport static org.hisp.dhis.android.core.utils.Utils.isDeleted;%0A%0Apublic class ProgramRuleVariableHandler %7B%0A    private final ProgramRuleVariableStore programRuleVariableStore;%0A%0A    ProgramRuleVariableHandler(ProgramRuleVariableStore programRuleVariableStore) %7B%0A        this.programRuleVariableStore = programRuleVariableStore;%0A    %7D%0A%0A    public void handleProgramRuleVariables(List%3CProgramRuleVariable%3E programRuleVariables) %7B%0A        if (programRuleVariables == null) %7B%0A            return;%0A        %7D%0A%0A        deleteOrPersistProgramRuleVariables(programRuleVariables);%0A    %7D%0A%0A    private void deleteOrPersistProgramRuleVariables(List%3CProgramRuleVariable%3E programRuleVariables) %7B%0A        int size = programRuleVariables.size();%0A%0A        for (int i = 0; i %3C size; i++) %7B%0A            ProgramRuleVariable programRuleVariable = programRuleVariables.get(i);%0A%0A            if (isDeleted(programRuleVariable)) %7B%0A                programRuleVariableStore.delete(programRuleVariable.uid());%0A            %7D else %7B%0A                String programStageUid = null;%0A                if(programRuleVariable.programStage() != null) %7B%0A                    programStageUid = programRuleVariable.programStage().uid();%0A                %7D%0A%0A                String dataElementUid = null;%0A                if(programRuleVariable.dataElement() != null) %7B%0A                    dataElementUid = programRuleVariable.dataElement().uid();%0A                %7D%0A%0A                String trackedEntityAttributeUid = null;%0A                if(programRuleVariable.trackedEntityAttribute() != null) %7B%0A                    trackedEntityAttributeUid = programRuleVariable.trackedEntityAttribute().uid();%0A                %7D%0A%0A                int updatedRow = programRuleVariableStore.update(%0A                        programRuleVariable.uid(), programRuleVariable.code(),%0A                        programRuleVariable.name(), programRuleVariable.displayName(),%0A                        programRuleVariable.created(), programRuleVariable.lastUpdated(),%0A                        programRuleVariable.useCodeForOptionSet(),%0A                        programRuleVariable.program().uid(), programStageUid,%0A                        dataElementUid,%0A                        trackedEntityAttributeUid,%0A                        programRuleVariable.programRuleVariableSourceType(), programRuleVariable.uid()%0A                );%0A%0A                if (updatedRow %3C= 0) %7B%0A                    programRuleVariableStore.insert(%0A                            programRuleVariable.uid(), programRuleVariable.code(),%0A                            programRuleVariable.name(), programRuleVariable.displayName(),%0A                            programRuleVariable.created(), programRuleVariable.lastUpdated(),%0A                            programRuleVariable.useCodeForOptionSet(),%0A                            programRuleVariable.program().uid(), programStageUid,%0A                            dataElementUid,%0A                            trackedEntityAttributeUid,%0A                            programRuleVariable.programRuleVariableSourceType()%0A                    );%0A                %7D%0A            %7D%0A%0A        %7D
+arch.handlers.IdentifiableSyncHandlerImpl;%0Aimport org.hisp.dhis.android.core.common.IdentifiableObjectStore;%0Aimport org.hisp.dhis.android.core.data.database.DatabaseAdapter;%0A%0Apublic class ProgramRuleVariableHandler extends IdentifiableSyncHandlerImpl%3CProgramRuleVariable%3E %7B%0A%0A    ProgramRuleVariableHandler(IdentifiableObjectStore%3CProgramRuleVariable%3E programRuleVariableStore) %7B%0A        super(programRuleVariableStore);
 %0A   
@@ -2184,20 +2184,16 @@
 Handler(
-new 
 ProgramR
@@ -2208,20 +2208,23 @@
 bleStore
-Impl
+.create
 (databas
@@ -2242,9 +2242,8 @@
 %0A    %7D%0A%7D
-%0A

Unify ProgramRuleVariableHandler