package com.capgemini.reports.definition.r10report;

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.reports.bomlineholder.BOMLineHolder;
import com.capgemini.reports.bomlineholder.flattener.AbstractBomLineFlattener;
import com.capgemini.reports.bomlineholder.flattener.line.*;
import com.capgemini.reports.definition.r10report.lines.*;
import com.capgemini.reports.releasestatus.EffectivityBehaviourHelper;
import com.capgemini.reports.snecmaobjects.part.AbstractPart;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * Flattens a bomLine.
 */
public class R10BomLineFlattener extends AbstractBomLineFlattener<List<Map<R10Keys, String>>, DocumentExtractor> {

    private static final boolean VISIT_PART_BELOW_PART = false;
    private static final boolean RETRIEVE_PART_NUMBER_UNDER_RF_GENERIC = false;
    private static final boolean VISIT_PARTS_IN_PSEUDO_FOLDER = true;
    private static final boolean GENERATE_BROTHER_LINES_BEFORE_RECURSION = false;
    private final TcSession session;
    private int counter;

    /**
     * Usual constructor.
     */
    R10BomLineFlattener(final TcSession session) {
        super(EffectivityBehaviourHelper.visitOnlyUnitManagedParts(), VISIT_PARTS_IN_PSEUDO_FOLDER, RETRIEVE_PART_NUMBER_UNDER_RF_GENERIC,
                VISIT_PART_BELOW_PART, null, GENERATE_BROTHER_LINES_BEFORE_RECURSION);
        this.session = session;
        this.setPseudoFolderBehaviour(new R10PseudoFolderBrowser());
    }

    @Override
    protected AbstractQuad<List<Map<R10Keys, String>>, DocumentExtractor> makeQuad(final BOMLineHolder receptor, final BOMLineHolder rfReceptor,
                                                                                   final BOMLineHolder component, final BOMLineHolder rfComponent) {
        return new R10Quad(session, receptor, rfReceptor, component, rfComponent, counter++);
    }

    @Override
    protected AbstractTopLine<List<Map<R10Keys, String>>, DocumentExtractor> makeTopline(final BOMLineHolder aTopBomLine) {
        return new R10TopLine(aTopBomLine, counter++); // Nothing to do for this report: top line is ignored
    }

    @Override
    protected AbstractPartNumber<List<Map<R10Keys, String>>, DocumentExtractor> makePartNumber(final BOMLineHolder genericReceptor,
                                                                                               final BOMLineHolder rfGeneric, final BOMLineHolder partAero) {
        return null; // Nothing to do for this report: part number is ignored
    }

    @Override
    protected AbstractPartRfPart<List<Map<R10Keys, String>>, DocumentExtractor> makePartRfPart(final BOMLineHolder partReceptor,
                                                                                               final BOMLineHolder rfPartComponent, final BOMLineHolder partComponent) {
        return new R10PartRfPart(session, partReceptor, rfPartComponent, partComponent, counter++);
    }

    @Override
    protected AbstractPartPart<List<Map<R10Keys, String>>, DocumentExtractor> makePartPart(final BOMLineHolder partReceptor,
                                                                                           final BOMLineHolder partComponent) {
        return null; // Nothing to do for this report: top line is ignored
    }

    @Override
    protected AbstractReceptorLine<List<Map<R10Keys, String>>, DocumentExtractor> makeReceptorLine(final BOMLineHolder part,
                                                                                                   final BOMLineHolder rfPart) {
        return null; // Nothing to do for this report: When there is no Component, there is no line
    }

    @Override
    protected AbstractProductGeneric<List<Map<R10Keys, String>>, DocumentExtractor> makeProductGeneric(final BOMLineHolder productReceptor,
                                                                                                       final BOMLineHolder genericComponent, final BOMLineHolder rfGenericComponent) {
        return new R10ProductGeneric(session, productReceptor, genericComponent, rfGenericComponent, counter++);
    }

    private class R10PseudoFolderBrowser implements AbstractBomLineFlattener.DealWithAltOrDetPseudoFolder<List<Map<R10Keys, String>>, DocumentExtractor> {

        @Override
        public Collection<SnecmaLine<List<Map<R10Keys, String>>, DocumentExtractor>> dealWithIt(final BOMLineHolder alt, final AbstractPart partInPseudoFolder) {
            Collection<SnecmaLine<List<Map<R10Keys, String>>, DocumentExtractor>> list = new ArrayList<>();
            list.add(new R10AltPart(alt, partInPseudoFolder, counter++));
            return list;
        }
    }
}
