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

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.exceptions.KurtException;
import com.capgemini.reports.bomlineholder.BOMLineHolder;
import com.capgemini.reports.definition.r03report.ExecutionR03;
import com.capgemini.reports.definition.r03report.visitors.bomlineholder.R03BOMLineHolderVisitor;
import com.capgemini.reports.execution.mapconstructor.AbstractStaticTemplateMapConstructor;
import com.capgemini.reports.printing.PrintParameters;
import com.capgemini.reports.reports.IReportVisitor;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * Visit a R03 report.
 */
@Slf4j
@EqualsAndHashCode(callSuper = true)
public class R03Visitor extends AbstractStaticTemplateMapConstructor<ExecutionR03, BOMLineHolder> implements IReportVisitor<R03VisitorKeys, String> {
    private static final long serialVersionUID = -1999990931692459183L;

    private static final String EMPTY = "";

    protected final R03BOMLineHolderVisitor r03BOMLineHolderVisitor;

    /**
     * Constructor.
     */
    public R03Visitor() {
        super();
        this.r03BOMLineHolderVisitor = new R03BOMLineHolderVisitor();
    }

    private static String check(final Object anInput) {
        return anInput == null ? EMPTY : anInput.toString();
    }

    private List<Map<String, ?>> translate(final List<Map<R03VisitorKeys, String>> visitorMaps) {
        // Add empty fields in the first line
        Map<R03VisitorKeys, String> firstLine = visitorMaps.get(0);
        // Empty receptor
        firstLine.put(R03VisitorKeys.IDENTIFIANT_RECEPTEUR, EMPTY);
        firstLine.put(R03VisitorKeys.REVISION_RECEPTEUR, EMPTY);
        firstLine.put(R03VisitorKeys.NOM_RECEPTEUR, EMPTY);
        // Empty RF
        firstLine.put(R03VisitorKeys.REPERE_FONCTIONNEL, EMPTY);
        firstLine.put(R03VisitorKeys.REVISION_REPERE_FONCTIONNEL, EMPTY);
      firstLine.put(R03VisitorKeys.UIN, EMPTY);
        firstLine.put(R03VisitorKeys.EQUIVALENT_SNSSIN, EMPTY);
        firstLine.put(R03VisitorKeys.RESPONSABLE_REPERE, EMPTY);
        // Empty BOM
        firstLine.put(R03VisitorKeys.SUIVI_MONTAGE, EMPTY);
        firstLine.put(R03VisitorKeys.ALT, EMPTY);
        firstLine.put(R03VisitorKeys.SB, EMPTY);
        firstLine.put(R03VisitorKeys.QUANTITE_CUMULEE, EMPTY);
        firstLine.put(R03VisitorKeys.PANACHE, EMPTY);
        firstLine.put(R03VisitorKeys.QUANTITE, EMPTY);

        // Construct the map list expected by the printer
        List<Map<String, ?>> printerMaps = new ArrayList<>();
        for (Map<R03VisitorKeys, String> visitorMap : visitorMaps) {
            Map<String, String> printerMap = new HashMap<>();
            for (R03VisitorKeys key : R03VisitorKeys.values()) {
                printerMap.put(key.toString(), check(visitorMap.get(key)));
            }
            printerMaps.add(printerMap);
        }

        return printerMaps;
    }

    @Override
    public List<Map<String, ?>> visitReport(final BOMLineHolder holder) {
        List<Map<R03VisitorKeys, String>> visitorMaps = r03BOMLineHolderVisitor.visitTopReceptorBom(holder);
        return translate(visitorMaps);
    }

    @Override
    public void constructDataMaps(TcSession session, final PrintParameters printParameters, final BOMLineHolder topLine) throws KurtException {
        long start = System.currentTimeMillis();
        if (topLine == null) {

            throw new NoSuchElementException("No object structure found");
        }
        log.info("constructDataMaps ");

        // Parse all the snecma objects...
        List<Map<String, ?>> printerMaps = this.visitReport(topLine);
        log.debug("printer map size " + printerMaps.size());
        printParameters.addReportData(printerMaps);
        log.info("Filtering time : {} ms", System.currentTimeMillis() - start);
    }
}
