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

import com.capgemini.reports.bomlineholder.BOMLineHolder;
import com.capgemini.reports.bomlineholder.visitor.AbstractBOMLineHolderVisitor;
import com.capgemini.reports.definition.r22report.visitors.R22VisitorKeys;
import com.capgemini.reports.definition.r22report.visitors.snecmaobject.R22ComponentVisitor;
import com.capgemini.reports.definition.r22report.visitors.snecmaobject.R22ReceptorVisitor;
import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper;
import com.capgemini.reports.snecmaobjects.ISnecmaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * Visitor of an expansion of BOMLineHolder for the R22 report.
 */
public class R22BOMLineHolderVisitor extends AbstractBOMLineHolderVisitor<R22VisitorKeys, String> {
    private static final long serialVersionUID = -8251274449267683067L;
    private static final Logger LOGGER = LoggerFactory.getLogger(R22BOMLineHolderVisitor.class);
    private static final String SEMICOLON = " ; ";
    private static final String SPACE = " ";
    private ISnecmaObject topBomLine;

    public R22BOMLineHolderVisitor() {
        super(new R22ReceptorVisitor(), new R22ComponentVisitor(), EffectivityBehaviourHelper.visitAnyPart(), new R22AltOrDetBehaviour(), true,
                false, true);
    }

    @Override
    protected Map<R22VisitorKeys, String> visitThisReceptor(final BOMLineHolder aBomLine) {
        LOGGER.debug("visitThisReceptor {" + aBomLine.getUid() + "}");
        return aBomLine.getSnecmaObject().accept(receptorVisitor);
    }

    @Override
    protected Map<R22VisitorKeys, String> visitThisComponent(final BOMLineHolder aBomLine) {
        LOGGER.debug("visitThisComponent {" + aBomLine.getUid() + "}");
        Map<R22VisitorKeys, String> aMap = aBomLine.getSnecmaObject().accept(componentVisitor);
        // Put the BOMLine properties into the map
        if (aBomLine.getSnecmaObject().isGeneric() || aBomLine.getSnecmaObject().isPart()) {
            aMap.put(R22VisitorKeys.ALT, aBomLine.getBomAlt());
            aMap.put(R22VisitorKeys.SB, aBomLine.getBomSb());
            aMap.put(R22VisitorKeys.NQC, aBomLine.getBomQtyCumul());
            aMap.put(R22VisitorKeys.PANACHAGE, aBomLine.getBomPanache());
            aMap.put(R22VisitorKeys.COEFF, aBomLine.getBomQty());
        }
        return aMap;
    }

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

    @Override
    protected void mergeReceptorAndRepereReceptor(final Map<R22VisitorKeys, String> aReceptor, final Map<R22VisitorKeys, String> aRepereReceptor) {
        aReceptor.putAll(aRepereReceptor);
    }

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

    @Override
    protected void mergeRepereReceptorandAdmin(final Map<R22VisitorKeys, String> aRepereReceptor, final Map<R22VisitorKeys, String> anAdmin) {
        aRepereReceptor.putAll(anAdmin);
    }

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

    @Override
    protected void addToReport(final Map<R22VisitorKeys, String> aReceptor, final Map<R22VisitorKeys, 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);
    }

    /**
     * Format Item to display in report. <br>
     * EXPECTED : object id ; object revision id object name.
     *
     * @return reference item
     */
    public String getReferenceItem() {
        return topBomLine.getItemId() + SEMICOLON + topBomLine.getRevisionId() + SPACE + topBomLine.getName();
    }
}
