package com.capgemini.reports.definition.r03report.visitors.bomlineholder;

import com.capgemini.reports.bomlineholder.BOMLineHolder;
import com.capgemini.reports.bomlineholder.visitor.AbstractBOMLineHolderVisitor;
import com.capgemini.reports.definition.r03report.visitors.R03VisitorKeys;
import com.capgemini.reports.definition.r03report.visitors.snecmaobject.R03ComponentVisitor;
import com.capgemini.reports.definition.r03report.visitors.snecmaobject.R03ReceptorVisitor;
import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper;
import com.capgemini.reports.snecmaobjects.ISnecmaObject;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * Visitor of an expansion of BOMLineHolder for the R03 report.
 */
@Slf4j
@EqualsAndHashCode(callSuper = true)
public class R03BOMLineHolderVisitor extends AbstractBOMLineHolderVisitor<R03VisitorKeys, String> {
    private static final long serialVersionUID = -984208349993142537L;

    private static final String EMPTY_STRING = "";

    /**
     * Constructor.
     */
    public R03BOMLineHolderVisitor() {
        super(new R03ReceptorVisitor(), new R03ComponentVisitor(), EffectivityBehaviourHelper.visitAnyPart(), new R03AltOrDetBehaviour(), false,
                false, true);
    }

    @Override
    protected Map<R03VisitorKeys, String> visitThisReceptor(final BOMLineHolder aBomLine) {
        return aBomLine.getSnecmaObject().accept(receptorVisitor);
    }

    @Override
    protected Map<R03VisitorKeys, String> visitThisComponent(final BOMLineHolder aBomLine) {
        ISnecmaObject snecmaObject = aBomLine.getSnecmaObject();
        Map<R03VisitorKeys, String> aMap = snecmaObject.accept(componentVisitor);
        // Put the BOMLine properties into the map
        if ((snecmaObject.isGeneric()) || (snecmaObject.isPart())) {
            aMap.put(R03VisitorKeys.ALT, aBomLine.getBomAlt());
            aMap.put(R03VisitorKeys.SB, aBomLine.getBomSb());
            aMap.put(R03VisitorKeys.QUANTITE_CUMULEE, aBomLine.getBomQtyCumul());
            aMap.put(R03VisitorKeys.PANACHE, aBomLine.getBomPanache());
            aMap.put(R03VisitorKeys.QUANTITE, aBomLine.getBomQty());
            aMap.put(R03VisitorKeys.UIN, aBomLine.getUin());
        }
        if (aBomLine.getParentBomLine().getSnecmaObject().isPart() && snecmaObject.isPart()) {
            aMap.put(R03VisitorKeys.REPERE_FONCTIONNEL, EMPTY_STRING);
            aMap.put(R03VisitorKeys.REVISION_REPERE_FONCTIONNEL, EMPTY_STRING);
            aMap.put(R03VisitorKeys.SUIVI_MONTAGE, EMPTY_STRING);
            aMap.put(R03VisitorKeys.RESPONSABLE_REPERE, EMPTY_STRING);
            aMap.put(R03VisitorKeys.EQUIVALENT_SNSSIN, EMPTY_STRING);
        }
        return aMap;
    }

    @Override
    protected void visitSpecificFirstLine(final BOMLineHolder aTopBomLine) {
        Map<R03VisitorKeys, String> theFirstLine = aTopBomLine.getSnecmaObject().accept(getComponentVisitor());
        theReportTable.add(theFirstLine);
    }

    @Override
    protected void mergeReceptorAndRepereReceptor(final Map<R03VisitorKeys, String> aReceptor, final Map<R03VisitorKeys, String> aRepereReceptor) {
        // No used for R03 report
    }

    @Override
    protected void mergeComponentAndRepereComponent(final Map<R03VisitorKeys, String> aComponent, final Map<R03VisitorKeys, String> aRepereComponent) {
        aComponent.putAll(aRepereComponent);
    }

    @Override
    protected void mergeRepereReceptorandAdmin(final Map<R03VisitorKeys, String> aRepereReceptor, final Map<R03VisitorKeys, String> anAdmin) {
        // No used for R03 report
    }

    @Override
    protected void mergeRepereComponentandAdmin(final Map<R03VisitorKeys, String> aRepereComponent, final Map<R03VisitorKeys, String> anAdmin) {
        aRepereComponent.putAll(anAdmin);
    }

    @Override
    protected void addToReport(final Map<R03VisitorKeys, String> aReceptor, final Map<R03VisitorKeys, String> aComponent) {
        // Put the Receptor and Repere Receptor in the Component and modify the Component
        // Do not modify the receptor
        aComponent.putAll(aReceptor);

        // Add to the R22 report
        theReportTable.add(aComponent);
    }
}
