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

import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.framework.teamcenter.policies.PolicyLocation;
import com.capgemini.reports.ReportEnum;
import com.capgemini.reports.ReportLaunchTypeEnum;
import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum;
import com.capgemini.reports.database.manager.MngCriteriaVal.CriteriaValue;
import com.capgemini.reports.execution.AbstractExecutionReport;
import com.capgemini.reports.printing.Printer.PrintFormat;
import com.capgemini.reports.reports.parameters.EffectivityDate;
import com.capgemini.reports.reports.parameters.IChecker;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * This class controls the execution of a R13 report.
 *
 * @param <T> generic object for a report
 * @param <U> the objects sent by the data preparator to the Printer (FPP or ChangeRequest)
 */
@Getter
@Slf4j
@EqualsAndHashCode(callSuper = true)
public abstract class AbstractExecutionR13<T extends AbstractExecutionR13<T, U>, U> extends AbstractExecutionReport<T, List<U>> {

    // Policies
    protected static final PolicyLocation R13_POLICY_XML_FULL = PolicyLocation.make("R13_policy_full", "/xml/policies/r13report/R13_policy_full.xml");
    protected static final PolicyLocation R13_POLICY_XML_LIGHT = PolicyLocation.make("R13_policy_light", "/xml/policies/r13report/R13_policy_light.xml");
    private static final long serialVersionUID = 7486257915745387797L;
    // Priority parameter
    private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R13);
    // Revision rule parameter
    private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R13", DEFAULT_REVISION_RULE);
    // Launch type parameter
    private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R13");
    // Raw input parameters
    protected final String typeObject;
    protected final EffectivityDate finalDate;
    protected final EffectivityDate startDate;

    /**
     * Constructor.
     *
     * @param typeObject String - the type of the Object
     * @param finalDate  {@link Calendar} - the final date
     * @param startDate  {@link Calendar} - the previous date
     */
    AbstractExecutionR13(final String typeObject, final EffectivityDate finalDate, final EffectivityDate startDate) {
        super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE);
        this.typeObject = typeObject;
        this.finalDate = finalDate;
        this.startDate = startDate;
    }

    @Override
    public List<CriteriaValue> getLaunchData() {
        List<CriteriaValue> theCriteria = new ArrayList<>();
        String prevValue = (startDate == null) ? "" : startDate.formatAsInputCriteria();
        String finalValue = finalDate.formatAsInputCriteria();
        log.info("R13 input:" + typeObject + "\t" + prevValue + "\t" + finalValue);
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.TYPE_OBJET, typeObject));
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.DATE_DEBUT, prevValue));
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.DATE_FIN, finalValue));
        return theCriteria;
    }

    @Override
    public List<IChecker> getQuickChecks() {
        return new ArrayList<>();
    }

    @Override
    public PolicyLocation getPropertyPolicyForLongChecks() {
        return R13_POLICY_XML_LIGHT;
    }

    @Override
    public PolicyLocation getFullPolicy() {
        return R13_POLICY_XML_FULL;
    }

    @Override
    public List<IChecker> getLongChecks() {
        return new ArrayList<>();
    }

    @Override
    public ReportEnum getReportIdentifier() {
        return ReportEnum.REPORT_R13;
    }

    @Override
    public String getSpecifiedFileName() {
        String separator = "_";
        StringBuilder builder = new StringBuilder("R13_").append(typeObject).append(separator);
        if (startDate != null) {
            builder.append(startDate.getFormattedDateForFrenchUser()).append(separator).append(finalDate.getFormattedDateForFrenchUser());
        } else {
            builder.append("NoPrevDate").append(separator).append("NoFinalDate");
        }

        return builder.toString();
    }

    @Override
    public PrintFormat getPrintingFormat() {
        return PrintFormat.XLSX;
    }
}
