package com.capgemini.reports.definition.r13report.datapreparator;

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.exceptions.KurtException;
import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery;
import com.capgemini.framework.teamcenter.resolution.filtering.TcTypeExclusionFilter;
import com.capgemini.reports.ItemRevisionComparator;
import com.capgemini.reports.changeobjects.change.TcChangeRequestRevision;
import com.capgemini.reports.definition.r13report.execution.ExecutionR13CR;
import com.capgemini.reports.definition.r13report.printer.R13PrinterCR;
import com.capgemini.reports.execution.IDataReportPreparator;
import com.capgemini.reports.printing.PrintParameters;
import com.capgemini.reports.teamcenter.queries.saved.ChangeRequestWithSeqQuery;
import com.teamcenter.soa.client.model.strong.ItemRevision;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * This class will allow to prepare data and findAll back data for making report R13CR.
 */
@Slf4j
public class DataReportPreparatorR13CR extends AbstractDataReportPreparatorR13<ExecutionR13CR> implements IDataReportPreparator<ExecutionR13CR> {
    private static final long serialVersionUID = 811112181278567085L;

    // Configuration
    private static final String FINISHED = "Finished";
    private static final String CANCELLED = "Cancelled";
    private static final String SB_DISTRIBUTED = "SB distributed";

    private static final String CR_DEPRECIE_REVISION = "CR Déprécié Revision";
    private static final String PV4_CR_DEPREC_REVISION = "PV4_CR_DEPRECRevision";

    private static final TcTypeExclusionFilter FILTER_EXCLUDE_FINISHED_CANCELLED_DISTRIBUTED = new TcTypeExclusionFilter(FINISHED, CANCELLED, SB_DISTRIBUTED);
    private static final TcTypeExclusionFilter FILTER_EXCLUDE_CR_DEPREC = new TcTypeExclusionFilter(CR_DEPRECIE_REVISION, PV4_CR_DEPREC_REVISION);

    @Override
    protected boolean validateStatusByName(final String statusName) {
        return FILTER_EXCLUDE_FINISHED_CANCELLED_DISTRIBUTED.isIncluded(statusName);
    }

    @Override
    protected boolean specificValidation(final TcSession session, final ItemRevision itemRev) {
        // Filter out deprecated CRs
        return FILTER_EXCLUDE_CR_DEPREC.isIncluded(itemRev.getTypeObject().getName());
    }

    @Override
    protected PrintParameters buildValidatedChangeObjects(final TcSession session, ExecutionR13CR report) throws KurtException {
        AbstractReplicatedQuery<ItemRevision, ?> query = new ChangeRequestWithSeqQuery(session);
        addParamPeriod(query, report);
        List<TcChangeRequestRevision> data = new ArrayList<>();
        for (ItemRevision itemRev : validateChangeObjects(query.searchAllObjects().findAll(), session)) {
            data.add(new TcChangeRequestRevision(session, itemRev));
        }

        R13PrinterCR printer = new R13PrinterCR();
        PrintParameters printParameters = printer.makeMasterTemplate(report, data);
        printer.constructDataMaps(session, printParameters, data);

        return printParameters;
    }

    private List<ItemRevision> validateChangeObjects(final List<ItemRevision> objects, final TcSession session) {
        List<ItemRevision> validatedObjects = new ArrayList<>();
        Collections.sort(objects, new ItemRevisionComparator());
        for (ItemRevision itemRev : objects) {
            if (itemRev == null) {
                continue;
            }
            // Common treatment on status
            if (!isStatusValid(session, itemRev)) {
                continue;
            }
            // Specific treatment if required (FPP)
            if (!specificValidation(session, itemRev)) {
                continue;
            }
            validatedObjects.add(itemRev);
        }

        return validatedObjects;
    }
}
