package com.capgemini.reports.definition.r15r16r17reports.r16report;

import com.capgemini.framework.common.StringHelper;
import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.exceptions.KurtException;
import com.capgemini.reports.definition.r15r16r17reports.AbstractR15R16R17Printer;
import com.capgemini.reports.definition.r15r16r17reports.CommunR15R16R17ComponentVisitor;
import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys;
import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys.Page2;
import com.capgemini.reports.definition.r15r16r17reports.R15R16R17R24R25Keys.SpecificR15R16;
import com.capgemini.reports.execution.mapconstructor.IMapConstructor;
import com.capgemini.reports.printing.PrintParameters;
import com.capgemini.reports.snecmaobjects.part.PartAeroRevision;
import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;

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

/**
 * This class is able to put the data gathered by an {@link ExecutionR16} into some {@link PrintParameters} for printing.
 */
@Slf4j
@EqualsAndHashCode(callSuper = true)
public class R16Printer extends AbstractR15R16R17Printer<ExecutionR16> implements IMapConstructor<ExecutionR16, ExecutionR16> {

    private static final long serialVersionUID = -7722864354275704498L;

    private static final String EMPTY_STRING = StringHelper.EMPTY;
    private static final String UNKNOWN_STR = "???";
    private static final String SANS_OBJET = "Sans objet";
    private static final String NOT_APPLICABLE = "Not applicable ";

    @Override
    protected List<Map<Page2, String>> addExtraDocLines(final ExecutionR16 execution) {
        return new ArrayList<>();
    }

    @Override
    protected void addOptionalParameters(final ExecutionR16 execution, final PrintParameters mainReport) {
      Map<R15R16R17R24R25Keys, Object> params = new EnumMap<>(R15R16R17R24R25Keys.class);
        List<PartAeroRevision> partNumberRevList = execution.getPartNumberRevList();
        if (partNumberRevList != null && !partNumberRevList.isEmpty()) {
          Map<R15R16R17R24R25Keys, String> map = new EnumMap<>(R15R16R17R24R25Keys.class);
            if (partNumberRevList.size() == 1) {
                map = partNumberRevList.get(0).accept(getVisitor(execution.isFrench()));
              map.remove(R15R16R17R24R25Keys.PART_VERSION);
              map.put(R15R16R17R24R25Keys.PART_VERSION, EMPTY_STRING);
            } else {
              map.put(R15R16R17R24R25Keys.ITEM_ID, UNKNOWN_STR);
              map.put(R15R16R17R24R25Keys.PART_NUMBER, UNKNOWN_STR);
              map.put(R15R16R17R24R25Keys.MANUFACTURER_CODE, UNKNOWN_STR);
              map.put(R15R16R17R24R25Keys.PART_VERSION, EMPTY_STRING);
              map.put(R15R16R17R24R25Keys.FRENCH_DESIGNATION, UNKNOWN_STR);
              map.put(R15R16R17R24R25Keys.ENGLISH_DESIGNATION, UNKNOWN_STR);
              map.put(R15R16R17R24R25Keys.OBTURATION, execution.isFrench() ? SANS_OBJET : NOT_APPLICABLE);
              map.put(R15R16R17R24R25Keys.CLASSIFICATION, "-");
              map.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, UNKNOWN_STR);
              map.put(R15R16R17R24R25Keys.LOG_DOCUMENT, execution.isFrench() ? SANS_OBJET : NOT_APPLICABLE);
            }
            params.putAll(map);
        } else {
            params.putAll(execution.getGenericRev().accept(getVisitor(execution.isFrench())));
        }
      params.put(R15R16R17R24R25Keys.MT_NUMBER, EMPTY_STRING);
      params.put(R15R16R17R24R25Keys.PREVIOUS_RELEASE_DATE, EMPTY_STRING);
      params.put(R15R16R17R24R25Keys.ITEM_ID, execution.getArticleId());
        mainReport.addReportParameters(params);

        Map<SpecificR15R16, Object> map = new EnumMap<>(SpecificR15R16.class);
        boolean isFrench = execution.isFrench();
        String frontiereAvion = execution.getFrontiereAvion();
        map.put(SpecificR15R16.INSTALLATION_INTERFACE, isFrench ? french(frontiereAvion) : english(frontiereAvion));
        String frontiereCooperant = execution.getFrontiereCooperant();
        map.put(SpecificR15R16.PARTNER_INTERFACE, isFrench ? french(frontiereCooperant) : english(frontiereCooperant));
        map.put(SpecificR15R16.PRODUCT_UNIT, execution.getProduitUnit());
        map.put(SpecificR15R16.SUB_TITLE, execution.isDefCertifiee()
                ? "Documents de définition et procédés\nDefinition and process documents"
                : "Documents de définition et procédés et pratiques de réalisation\nDefinition and process documents and manufacturing practices");
        mainReport.addReportParameters(map);
        mainReport.addReportParameter(SpecificR15R16.IS_PREVIOUS_DEF.toString(), false);
    }

    @Override
    protected String getTitle(final ExecutionR16 execution) {
        return execution.isDefCertifiee()
                ? "Définition technique de l'article\nPart Definition"
                : "Définition de réalisation de l'article\nPart Manufacturing definition";
    }

    @Override
    protected IComponentVisitor<Map<R15R16R17R24R25Keys, String>> getVisitor(final boolean isFrench) {
        return new CommunR15R16R17ComponentVisitor(isFrench);
    }

    @Override
    public void constructDataMaps(TcSession session, final PrintParameters printParameters, final ExecutionR16 data) throws KurtException {
        long start = System.currentTimeMillis();
        this.print(data, printParameters);
        log.trace("Execution time : {} ms for {}", System.currentTimeMillis() - start, "data filtering");
    }
}
