package com.capgemini.reports.definition.r15r16r17reports;

import com.capgemini.framework.common.LanguageHelper;
import com.capgemini.framework.common.StringHelper;
import com.capgemini.reports.snecmaobjects.admin.RFAdminAGRevision;
import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision;
import com.capgemini.reports.snecmaobjects.admin.RFAdminARevision;
import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision;
import com.capgemini.reports.snecmaobjects.descriptif.DescriptifRevision;
import com.capgemini.reports.snecmaobjects.generic.AbstractGenericRevision;
import com.capgemini.reports.snecmaobjects.generic.GenericAssembRevision;
import com.capgemini.reports.snecmaobjects.generic.GenericRevision;
import com.capgemini.reports.snecmaobjects.mockup.MockupRevision;
import com.capgemini.reports.snecmaobjects.part.*;
import com.capgemini.reports.snecmaobjects.product.ProductRevision;
import com.capgemini.reports.snecmaobjects.rf.RFGenericRevision;
import com.capgemini.reports.snecmaobjects.rf.RFPartAssembRevision;
import com.capgemini.reports.snecmaobjects.rf.RFPartRevision;
import com.capgemini.reports.snecmaobjects.supermodel.SuperModelRevision;
import com.capgemini.reports.snecmaobjects.visitor.IComponentVisitor;

import java.util.EnumMap;
import java.util.Map;

/**
 * Visitor for a R15 or a R17 report.
 */
public class CommunR15R16R17ComponentVisitor implements IComponentVisitor<Map<R15R16R17R24R25Keys, String>> {

    private static final String YES = "Yes";
    private static final String OUI = "Oui";
    private static final String DASH_STR = "-";
    private static final long serialVersionUID = -4111258059351094185L;
    private static final String SANS_OBJET = "Sans objet";
    private static final String NOT_APPLICABLE = "Not applicable ";
    private final boolean isFrench;

    /**
     * Constructor.
     *
     * @param isFrench boolean - the language of the report.
     */
    public CommunR15R16R17ComponentVisitor(final boolean isFrench) {
        this.isFrench = isFrench;
    }

    private static String french(final String string) {
        return LanguageHelper.french(string);
    }

    private static String english(final String string) {
        return LanguageHelper.english(string);
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final ProductRevision aProductRev) {
        // No use
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final GenericRevision aGenericRev) {
        return giveGenericProperties(aGenericRev);
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(SuperModelRevision aSuperModelRev) {
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final GenericAssembRevision aGenericAssembRev) {
        return giveGenericProperties(aGenericAssembRev);
    }

  private Map<R15R16R17R24R25Keys, String> giveGenericProperties(final AbstractGenericRevision aGenericRev) {
    Map<R15R16R17R24R25Keys, String> theMap = new EnumMap<>(R15R16R17R24R25Keys.class);
    theMap.put(R15R16R17R24R25Keys.ITEM_ID, aGenericRev.getItemId());
    theMap.put(R15R16R17R24R25Keys.PART_NUMBER, aGenericRev.getItemId());
    theMap.put(R15R16R17R24R25Keys.MANUFACTURER_CODE, aGenericRev.getResponsableConception());
    theMap.put(R15R16R17R24R25Keys.FRENCH_DESIGNATION, aGenericRev.getName());
    theMap.put(R15R16R17R24R25Keys.ENGLISH_DESIGNATION, aGenericRev.getDesignationEN());
    theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE);
    theMap.put(R15R16R17R24R25Keys.CLASSIFICATION, DASH_STR);
    theMap.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, isFrench ? OUI : YES);
    theMap.put(R15R16R17R24R25Keys.LOG_DOCUMENT, isFrench ? SANS_OBJET : NOT_APPLICABLE);
    theMap.put(R15R16R17R24R25Keys.PART_VERSION, StringHelper.EMPTY);
        return theMap;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final AlternateRevision aAlternateRev) {
      Map<R15R16R17R24R25Keys, String> theMap = giveNotPartMatProperties(aAlternateRev);
        String obturation = aAlternateRev.getObturation();
      theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? french(obturation) : english(obturation));
        return theMap;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final DETRevision aDetRev) {
      Map<R15R16R17R24R25Keys, String> theMap = giveNotPartMatProperties(aDetRev);
        String obturation = aDetRev.getObturation();
      theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? french(obturation) : english(obturation));
        return theMap;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final PartAeroRevision aPartAeroRev) {
      Map<R15R16R17R24R25Keys, String> theMap = giveNotPartMatProperties(aPartAeroRev);
        String obturation = aPartAeroRev.getObturation();
      theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? french(obturation) : english(obturation));
        return theMap;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final PartNoAeroRevision aPartNoAeroRev) {
      Map<R15R16R17R24R25Keys, String> theMap = giveNotPartMatProperties(aPartNoAeroRev);
      theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE);
        return theMap;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final PartAssembRevision aPartAssembRev) {
      Map<R15R16R17R24R25Keys, String> theMap = giveNotPartMatProperties(aPartAssembRev);
      theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE);
        return theMap;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final PartMatRevision aPartMatRev) {
      Map<R15R16R17R24R25Keys, String> theMap = givePartProperties(aPartMatRev); // This one does NOT use giveNotPartMatProperties (obviously)
      theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE);
        String classementMat = aPartMatRev.getClassementMat();
      theMap.put(R15R16R17R24R25Keys.CLASSIFICATION, (classementMat == null || classementMat.isEmpty()) ? DASH_STR : classementMat);
      theMap.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, isFrench ? SANS_OBJET : NOT_APPLICABLE);
      theMap.put(R15R16R17R24R25Keys.LOG_DOCUMENT, isFrench ? SANS_OBJET : NOT_APPLICABLE);
        return theMap;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final StandardRevision aStandardRev) {
      Map<R15R16R17R24R25Keys, String> theMap = giveNotPartMatProperties(aStandardRev);
      theMap.put(R15R16R17R24R25Keys.OBTURATION, isFrench ? SANS_OBJET : NOT_APPLICABLE);
        return theMap;
    }

  private Map<R15R16R17R24R25Keys, String> givePartProperties(final AbstractPart aPart) {
    Map<R15R16R17R24R25Keys, String> theMap = new EnumMap<>(R15R16R17R24R25Keys.class);
    theMap.put(R15R16R17R24R25Keys.ITEM_ID, aPart.getItemId());
    theMap.put(R15R16R17R24R25Keys.PART_NUMBER, aPart.getItemId());
    theMap.put(R15R16R17R24R25Keys.MANUFACTURER_CODE, aPart.getResponsableConception());
    theMap.put(R15R16R17R24R25Keys.PART_VERSION, aPart.getRevisionId());
    theMap.put(R15R16R17R24R25Keys.FRENCH_DESIGNATION, aPart.getName());
    theMap.put(R15R16R17R24R25Keys.ENGLISH_DESIGNATION, aPart.getDesignationEN());
        return theMap;
    }

  private Map<R15R16R17R24R25Keys, String> giveNotPartMatProperties(final AbstractPart aPart) {
    Map<R15R16R17R24R25Keys, String> theMap = givePartProperties(aPart);
        String classement = aPart.getClassement();
    theMap.put(R15R16R17R24R25Keys.CLASSIFICATION, (classement == null || classement.isEmpty()) ? DASH_STR : classement);
        String suiviUtilisation = aPart.getSuiviUtilisation();
    theMap.put(R15R16R17R24R25Keys.FIELD_OPN_SERIALISATION, isFrench ? french(suiviUtilisation) : english(suiviUtilisation));
        String documentControle = aPart.getDocumentControle();
    theMap.put(R15R16R17R24R25Keys.LOG_DOCUMENT, isFrench ? french(documentControle) : english(documentControle));
        return theMap;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final RFGenericRevision aRfGenericRev) {
        // No use
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final RFPartAssembRevision aRfPartAssembRev) {
        // No use
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final RFPartRevision aRfPartRev) {
        // No use
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final RFAdminRevision aRfAdminRev) {
        // No use
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final RFAdminARevision aRfAdminARev) {
        // No use
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final RFAdminAPRevision aRfAdminAPRev) {
        // No use
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final RFAdminAGRevision aRfAdminAGRev) {
        // No use
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final MockupRevision aMockupRev) {
        // This object is not use in this report
        return null;
    }

    @Override
    public Map<R15R16R17R24R25Keys, String> visitComponent(final DescriptifRevision aDescriptifRev) {
        // This object is not use in this report
        return null;
    }
}
