package com.capgemini.reports.definition.r07report.data.filter.comparators.rf;

import com.capgemini.reports.bomlineholder.BOMLineHolder;
import com.capgemini.reports.bomlineholder.BOMLineHolderHelper;
import com.capgemini.reports.exceptions.InvalidInputException;
import com.capgemini.reports.exceptions.NotFoundException;
import com.capgemini.reports.snecmaobjects.admin.RFAdminAPRevision;
import com.capgemini.reports.snecmaobjects.admin.RFAdminRevision;
import com.capgemini.reports.snecmaobjects.rf.AbstractRF;
import lombok.extern.slf4j.Slf4j;

/**
 * Comapres two RF Parts together.
 */
@Slf4j
public class RfPartComparator extends RfComparator {
    private static final long serialVersionUID = -185746619920561652L;

    RfPartComparator() {
    }

    @Override
    public int compare(final BOMLineHolder thisRfBL, final BOMLineHolder otherRfBL) {
        // Compare part data
        AbstractRF thisRf = (AbstractRF) thisRfBL.getSnecmaObject();
        AbstractRF otherRf = (AbstractRF) otherRfBL.getSnecmaObject();
        int cmp = thisRf.getName().compareTo(otherRf.getName());
        if (cmp != 0) {
            return cmp;
        }
        cmp = safeCmp(thisRf.getEquivalentSnsSin(), otherRf.getEquivalentSnsSin());
        if (cmp != 0) {
            return cmp;
        }
        // Bowse children for RF Admin
        cmp = compareRfAdmin(thisRfBL, otherRfBL);
        if (cmp != 0) {
            return cmp;
        }
        // Bowse children for RF Admin AP
        cmp = compareRfAdminAP(thisRfBL, otherRfBL);
        return cmp;
    }

    private int compareRfAdmin(final BOMLineHolder thisRfBL, final BOMLineHolder otherRfBL) {
        // Bowse children for RF Admin
        RFAdminRevision thisRfAdmin = findRfAdmin(thisRfBL);
        RFAdminRevision otherRfAdmin = findRfAdmin(otherRfBL);
        if (thisRfAdmin == null || otherRfAdmin == null) {
            if (thisRfAdmin == null && otherRfAdmin == null) {
                log.warn("No RF Admin found below both compared RF Generics: " + thisRfBL.getSnecmaObject().getName() + " / "
                        + otherRfBL.getSnecmaObject().getName());
                // No difference, then!
                return 0;
            } else {
                log.warn("No RF Admin found below one of the compared RF Generics: " + thisRfBL.getSnecmaObject().getName() + " / "
                        + otherRfBL.getSnecmaObject().getName());
                return 1; // Diff found
            }
        }
        return safeCmp(thisRfAdmin.getResponsableRepere(), otherRfAdmin.getResponsableRepere());
    }

    private int compareRfAdminAP(final BOMLineHolder thisRfBL, final BOMLineHolder otherRfBL) {
        // Bowse children for RF Admin
        RFAdminAPRevision thisRfAdminAP = findRfAdminAP(thisRfBL);
        RFAdminAPRevision otherRfAdminAP = findRfAdminAP(otherRfBL);

        if (thisRfAdminAP == null || otherRfAdminAP == null) {
            if (thisRfAdminAP == null && otherRfAdminAP == null) {
                log.warn("No RF Admin AP found below both compared RF Parts: " + thisRfBL.getSnecmaObject().getName() + " / "
                        + otherRfBL.getSnecmaObject().getName());
                return 0;
            } else {
                log.warn("No RF Admin AP found below one of the compared RF Parts: " + thisRfBL.getSnecmaObject().getName() + " / "
                        + otherRfBL.getSnecmaObject().getName());
                return 1;
            }
        }
        return safeCmp(thisRfAdminAP.getSuiviMontage(), otherRfAdminAP.getSuiviMontage());
    }

    private RFAdminAPRevision findRfAdminAP(final BOMLineHolder aRF) {
        try {
            return BOMLineHolderHelper.findRfAdminAP(aRF);
        } catch (NotFoundException | InvalidInputException nfe) {
            log.warn("No RF Admin AP found below: " + aRF.getSnecmaObject().getName(), nfe);
            return null;
        }
    }
}
