package com.capgemini.reports.bomlineholder.flattener;

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.reports.bomlineholder.BOMLineHolder;
import com.capgemini.reports.bomlineholder.ISnecmaLineProcessor;
import com.capgemini.reports.bomlineholder.flattener.line.AbstractReceptorRepere;
import com.capgemini.reports.bomlineholder.flattener.line.SnecmaLine;
import com.capgemini.reports.bomlineholder.visitor.BomLineBrowser;
import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper;
import com.capgemini.reports.snecmaobjects.part.AbstractPart;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

/**
 * This class implements the interface {@link ISnecmaLineProcessor} and inherits of {@link BomLineBrowser}. It defines what kind of behavior it will adopt during the exploration of data.
 *
 * @param <RR> a class representing a, {@link AbstractReceptorRepere}
 */
@Getter
public abstract class AbstractRepereFlattener<RR extends AbstractReceptorRepere<?, ?>> extends BomLineBrowser implements ISnecmaLineProcessor {

    private final List<RR> config = new ArrayList<>();

    /**
     * Constructor.
     *
     * @param effectivityBehaviour
     * @param visitPartsInPseudoFolder
     * @param retrievePartNumberUnderRfGeneric
     * @param visitPartBelowPart
     * @param deeplyExplosion
     */
    public AbstractRepereFlattener(final EffectivityBehaviourHelper effectivityBehaviour, final boolean visitPartsInPseudoFolder,
                                   final boolean retrievePartNumberUnderRfGeneric, final boolean visitPartBelowPart, final boolean deeplyExplosion) {
        super(effectivityBehaviour, visitPartsInPseudoFolder, retrievePartNumberUnderRfGeneric, visitPartBelowPart);
        if (deeplyExplosion) {
            this.setProcessor(this);
        } else {
            this.setPreProcessor(this);
        }
    }

    @Override
    public final void visitTopBom(final BOMLineHolder aTopBom) {
        // Nothing to do
    }

    @Override
    public final void visitQuad(final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder component,
                                final BOMLineHolder rfComponent) {
        // Nothing to do
    }

    @Override
    public final void visitProductGeneric(final BOMLineHolder productReceptor, final BOMLineHolder genericComponent,
                                          final BOMLineHolder rfGenericComponent) {
        // Nothing to do
    }

    @Override
    public final void visitPartNumber(final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, final BOMLineHolder child) {
        // Nothing to do
    }

    @Override
    public final void visitPartAsComponent(final BOMLineHolder part, final BOMLineHolder rfPart, final BOMLineHolder child) {
        // Nothing to do
    }

    @Override
    public final void visitPartPart(final BOMLineHolder fatherPart, final BOMLineHolder childPart) {
        // Nothing to do
    }

    @Override
    public final void visitPartsInPseudoFolder(final BOMLineHolder aPart, final AbstractPart child) {
        // Nothing to do
    }

    @Override
    public final void visitReceptorWithoutComponent(final BOMLineHolder part, final BOMLineHolder rfPart) {
        // Nothing to do
    }

    @Override
    public void visitReceptorRepere(final TcSession session, final BOMLineHolder anObject, final BOMLineHolder aRF) {
        RR receptorRepere = makeRepairReceptorLine(session, anObject, aRF);
        if (receptorRepere != null) {
            config.add(receptorRepere);
        }
    }

    /**
     * Method which allow to make a receptor-repere {@link SnecmaLine}.
     *
     * @param session
     * @param anObject          an object
     * @param functionnalRepere its RF
     * @return the {@link AbstractReceptorRepere}
     */
    public abstract RR makeRepairReceptorLine(final TcSession session, final BOMLineHolder anObject, final BOMLineHolder functionnalRepere);
}
