package com.capgemini.reports.definition.r01report;

import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.framework.teamcenter.policies.PolicyLocation;
import com.capgemini.reports.JasperTemplate;
import com.capgemini.reports.ReportEnum;
import com.capgemini.reports.ReportLaunchTypeEnum;
import com.capgemini.reports.bomlineholder.BOMLineHolder;
import com.capgemini.reports.builder.R01Builder;
import com.capgemini.reports.builder.ReportBuilder;
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.execution.IDataReportPreparator;
import com.capgemini.reports.printing.Printer.PrintFormat;
import com.capgemini.reports.reports.parameters.*;
import com.capgemini.reports.reports.parameters.Generics.GenericType;
import com.capgemini.reports.reports.parameters.checker.*;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

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

/**
 * Obtain data for report R01.<br>
 * Contain {@link IChecker} for a report's construction
 */
@Getter
@EqualsAndHashCode(callSuper = true)
public class ExecutionR01 extends AbstractExecutionReport<ExecutionR01, BOMLineHolder> {
  private static final long serialVersionUID = -2173366731814318218L;

    private static final DataReportPreparatorR01 DATA_REPORT_PREPARATOR_R01 = new DataReportPreparatorR01();

    // Policies parameters
    private static final PolicyLocation R01_POLICY_XML_LIGHT =
            PolicyLocation.make("R01_policy_light", "/xml/policies/r01report/R01_policy_light.xml");
    private static final PolicyLocation R01_POLICY_XML_FULL = PolicyLocation.make("R01_policy_full", "/xml/policies/r01report/R01_policy_full.xml");
    /**
     * Policy for inspecting Alternates and DETs more closely (i.e. looking into their pseudo-folders for alternative parts).
     */
    public static final PolicyLocation R01_POLICY_XML_ALT = PolicyLocation.make("R01_policy_alt", "/xml/policies/r01report/R01_policy_alt.xml");


    // Launch type parameter
    private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R01");

    // Revision rule parameter
    private static final String REPORT_REVISION_RULE =
            SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R01", DEFAULT_REVISION_RULE);

    // Priority parameter
    private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R01);

    // Internal working data
    private final Generics generic;
    private final MonoMulti monoMulti;
    private final ProductUnit productUnit;
    private final EffectivityDate effectivityDate;
    private final boolean isSuperModelBOM;

    @Setter
    private BOMLineHolder topLine;

    /**
     * Constructor
     *
     * @param aProductUnit    {@link ProductUnit} - the product and unit
     * @param aGeneric        le generic {@link Generics} - represent the generic. Can be null if the wanted configuration is only with the Product and the Unit.
     * @param aMonoMulti      {@link MonoMulti} - represent the type of resolution structure
     * @param effectivityDate {@link EffectivityDate} - represent the effectivity date
     */
    public ExecutionR01(final ProductUnit aProductUnit, final Generics aGeneric, final MonoMulti aMonoMulti, final EffectivityDate effectivityDate, final boolean isSuperModelBOM) {
        super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE);
        this.productUnit = aProductUnit;
        this.generic = aGeneric;
        this.monoMulti = aMonoMulti;
        this.effectivityDate = effectivityDate;
        this.isSuperModelBOM = isSuperModelBOM;
    }

    @Override
    public List<CriteriaValue> getLaunchData() {
        List<CriteriaValue> theCriteria = new ArrayList<>();
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, productUnit.getProductID()));
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT, productUnit.getUnitStr()));
        if (generic.getType() == GenericType.GENERIC) {
            theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, generic.getID()));
        }
        if (generic.getType() == GenericType.GENERIC_ASSEMB) {
            theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, generic.getID()));
        }
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.MONO_MULTI, monoMulti.toString()));
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.SUPERMODEL, Boolean.toString(isSuperModelBOM)));
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivityDate.formatAsInputCriteria()));
        return theCriteria;
    }

    @Override
    public String getSpecifiedFileName() {
        String separator = "-";
        StringBuilder builder = new StringBuilder("R01-");
        if (generic.getType() != GenericType.ONLY_PRODUCT) {
            builder.append(generic.getID()).append(separator);
        }
        builder.append(productUnit.getProductID()).append(separator);
        builder.append(productUnit.getUnit()).append(separator);
        builder.append(monoMulti.toString());
        return builder.toString();
    }

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

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

    @Override
    public List<IChecker> getQuickChecks() {
        List<IChecker> quickChecks = new ArrayList<>();
        quickChecks.add(new GenericExistenceChecker(generic));
        quickChecks.add(new ProductChecker(productUnit.getProductID()));
        quickChecks.add(new ProductUnitChecker(productUnit));
        quickChecks.add(new EffectivityChecker(effectivityDate));
        return quickChecks;
    }

    @Override
    public List<IChecker> getLongChecks() {
        List<IChecker> longChecks = new ArrayList<>();
        longChecks.add(new GenericUnderProductUnitChecker(generic));
        return longChecks;
    }

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

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

    @Override
    public String getTemplateLocation() {
        return JasperTemplate.TEMPLATE_R01.getFilepath();
    }

    @Override
    public IDataReportPreparator<ExecutionR01> getDataPreparator() {
        return DATA_REPORT_PREPARATOR_R01;
    }

    @Override
    public AbstractExecutionReport<?, ?> cloneTemplateToExecution() {
        return new ExecutionR01(productUnit, generic, monoMulti, effectivityDate, isSuperModelBOM);
    }

    @Override
    public Class<? extends ReportBuilder> getReportBuilderClass() {
        return R01Builder.class;
    }
}
