package com.capgemini.reports.bomlineholder;

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.reports.snecmaobjects.part.AbstractPart;

/**
 * Interface for objects who can perform an action on a Snecma Bom.<br>
 * Provides special methods that act on every possible representation of a Snecma Bom Line, usually comprised of at least a Receptor and a Component.
 */
public interface ISnecmaLineProcessor {
    /**
     * Behaviour to be defined for the very first element of the nomenclature, which usually doen't have a Repere, etc.
     *
     * @param aTopBom the {@link BOMLineHolder} holding the top Object (usually a Generic, or a Product, sometimes a Part.
     */
    void visitTopBom(final BOMLineHolder aTopBom);

    /**
     * Behaviour to be defined when a 'full' line of objects is found.<br>
     * A 'full' line consists of:
     * <ol>
     * <li></li>a Receptor like a Part, a Generic or a Product
     * <li></li>a Repere Fonctionnel associated with the receptor
     * <li></li>a Component like a Generic or a Part
     * <li></li>a Repere Fonctionnel associated with the component
     * </ol>
     *
     * @param receptor    the Receptor inside its {@link BOMLineHolder}
     * @param rfReceptor  the Receptor's repere inside its {@link BOMLineHolder}
     * @param component   the Component inside its {@link BOMLineHolder}
     * @param rfComponent the Component's repere inside its {@link BOMLineHolder}
     */
    void visitQuad(final BOMLineHolder receptor, final BOMLineHolder rfReceptor, final BOMLineHolder component, final BOMLineHolder rfComponent);


    /**
     * Behaviour to be defined when a Product-Generic-RF Generic line is found.<br>
     *
     * @param productReceptor    the Receptor inside its {@link BOMLineHolder}
     * @param genericComponent   the Component inside its {@link BOMLineHolder}
     * @param rfGenericComponent the Component's repere inside its {@link BOMLineHolder}
     */
    void visitProductGeneric(final BOMLineHolder productReceptor, final BOMLineHolder genericComponent, final BOMLineHolder rfGenericComponent);

    /**
     * Behaviour to be defined when a PartNumber is encountered. <br>
     * A Part Number if always found in this structure (and only in this structure):
     * <ol>
     * <li></li>a GenericReceptor
     * <li></li>an only RF Generic below the Generic
     * <li></li>an only PartAero below the RF Generic
     * </ol>
     * Note the Generic may have other children than the RF Generic, like some RF Parts..<br>
     * Also not the RF Generic should have other children than the PrtAero, like RF Admins (who own additional data on the RF Generic), etc.
     *
     * @param genericReceptor
     * @param rfGeneric
     * @param child
     */
    void visitPartNumber(final BOMLineHolder genericReceptor, final BOMLineHolder rfGeneric, final BOMLineHolder child);

    /**
     * Behaviour to be defined when the top object is a Part (therefore without an RF Part) points to an RF Part which owns a Part.<br>
     * This method is only encountered (once) when the nomenclature explosion begins on as Part.
     *
     * @param part   the father Part
     * @param rfPart a RF Part below the father Part
     * @param child  a Part below the RF Part
     */
    void visitPartAsComponent(final BOMLineHolder part, final BOMLineHolder rfPart, final BOMLineHolder child);

    /**
     * Behaviour to be defined a Part poitns to an other Part in the nomenclature.<br>
     * At the lower levels of nomenclature, Parts can have Parts as their direct children, whith neither having a RF Part.
     *
     * @param fatherPart the father Part
     * @param childPart  the child Part
     */
    void visitPartPart(final BOMLineHolder fatherPart, final BOMLineHolder childPart);

    /**
     * Behaviour to be defined when encountering an Alt or a DET, which contain a Part in its pseudo-folders.<br>
     * This method is invoked only when <code>visitPartsInPseudoFolderw</code> is set to <code>true</code>.
     *
     * @param aPart the Alt or DET part
     * @param child a child Part found in the pseudo-folder
     */
    void visitPartsInPseudoFolder(final BOMLineHolder aPart, final AbstractPart child);

    /**
     * Behaviour to be defined when encountering a Receptor which has a Rf, but this Rf links to no component.
     *
     * @param part   the part receptor
     * @param rfPart the RfPart
     */
    void visitReceptorWithoutComponent(final BOMLineHolder part, final BOMLineHolder rfPart);

    /**
     * Behaviour to be defined when we need only a Receptor and a repere.
     *
     * @param session
     * @param anObject anObject can be a part or generic or a product
     * @param aRf      can be any kind of repair
     */
    void visitReceptorRepere(TcSession session, final BOMLineHolder anObject, final BOMLineHolder aRf);
}
