package com.capgemini.reports.definition.r10report;

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.R10Builder;
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.definition.r10report.ExecutionR10.ReportDataR10;
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.EffectivityDate;
import com.capgemini.reports.reports.parameters.Generics;
import com.capgemini.reports.reports.parameters.Generics.GenericType;
import com.capgemini.reports.reports.parameters.IChecker;
import com.capgemini.reports.reports.parameters.MonoMulti;
import com.capgemini.reports.reports.parameters.checker.*;
import lombok.AllArgsConstructor;
import lombok.Getter;

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

/**
 * Class responsible for executing a R10 report.
 */
@Getter
public class ExecutionR10 extends AbstractExecutionReport<ExecutionR10, ReportDataR10> {

    private static final String SEPARATOR = "-";

    private static final long serialVersionUID = 5053661528356709081L;

    // Policies parameters
    private static final PolicyLocation R10_POLICY_XML_LIGHT = PolicyLocation.make("R10_policy_light", "/xml/policies/r10report/R10_policy_light.xml");
    private static final PolicyLocation R10_POLICY_XML_FULL = PolicyLocation.make("R10_policy_full", "/xml/policies/r10report/R10_policy_full.xml");

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

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

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

    private final Generics generics;
    private final MonoMulti monoMulti;
    private final EffectivityDate effectivityDate;

    /**
     * Usual constructor.
     *
     * @param generics        the {@link Generics}
     * @param monoMulti       the level of explosion
     * @param effectivityDate the effectivity
     */
    public ExecutionR10(final Generics generics, final MonoMulti monoMulti, final EffectivityDate effectivityDate) {
        super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE);
        this.generics = generics;
        this.monoMulti = monoMulti;
        this.effectivityDate = effectivityDate;
    }

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

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

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

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

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

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

    @Override
    public String getSpecifiedFileName() {
        StringBuilder builder = new StringBuilder("R10-");
        if (generics.getType() == GenericType.GENERIC) {
            builder.append(generics.getID()).append(SEPARATOR);
        } else if (generics.getType() == GenericType.GENERIC_ASSEMB) {
            builder.append(generics.getID()).append(SEPARATOR);
        }
        builder.append(generics.getProductUnit().getProductID()).append(SEPARATOR);
        builder.append(generics.getProductUnit().getUnitStr()).append(SEPARATOR);
        builder.append((MonoMulti.MONO.equals(monoMulti)) ? "Mono" : "Multi").append(SEPARATOR);
        return builder.toString();
    }

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

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

    @Override
    public IDataReportPreparator<ExecutionR10> getDataPreparator() {
        return new DataReportPreparatorR10();
    }

    @Override
    public AbstractExecutionReport<?, ?> cloneTemplateToExecution() {
        return new ExecutionR10(generics, monoMulti, effectivityDate);
    }

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

    /**
     * Stores all data obtained from TC.
     */
    @AllArgsConstructor
    static class ReportDataR10 {
        private final BOMLineHolder config;

        public BOMLineHolder getConfig() {
            return config;
        }
    }
}
