package com.capgemini.reports.definition.r07report;

import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.framework.common.StringHelper;
import com.capgemini.framework.teamcenter.policies.PolicyLocation;
import com.capgemini.reports.ReportEnum;
import com.capgemini.reports.ReportLaunchTypeEnum;
import com.capgemini.reports.builder.R07Builder;
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.r07report.checker.R07ProductUnitChecker;
import com.capgemini.reports.definition.r07report.data.DataReportPreparatorR07;
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.Generics;
import com.capgemini.reports.reports.parameters.Generics.GenericType;
import com.capgemini.reports.reports.parameters.IChecker;
import com.capgemini.reports.reports.parameters.ProductUnit;
import com.capgemini.reports.reports.parameters.checker.GenericExistenceChecker;
import com.capgemini.reports.reports.parameters.checker.ProductChecker;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

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

/**
 * This class controls the execution of a R07 report.
 */
@Setter(value = AccessLevel.PROTECTED)
public class ExecutionR07 extends AbstractExecutionReport<ExecutionR07, ReportDataR07> {
    private static final long serialVersionUID = 584625053050646351L;

    // Policies
    private static final PolicyLocation R07_POLICY_XML_FULL = PolicyLocation.make("R07_policy_full", "/xml/policies/r07report/R07_policy_full.xml");
    private static final PolicyLocation R07_POLICY_XML_LIGHT = PolicyLocation.make("R07_policy_light", "/xml/policies/r07report/R07_policy_light.xml");
    // Launch type parameter
    private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R07");
    // Revision rule parameter
    private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R07", DEFAULT_REVISION_RULE);
    // Priority parameter
    private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R07);
    // Report parameters
    @Getter
    private final Generics genericParam1;
    @Getter
    private final Generics genericParam2;

    /**
     * Constructor. Will compare nomenclature for two generics.
     *
     * @param genericParam1 the 1st Generic
     * @param genericParam2 the 2nd Generic
     */
    public ExecutionR07(final Generics genericParam1, final Generics genericParam2) {
        super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE);
        this.genericParam1 = genericParam1;
        this.genericParam2 = genericParam2;
    }

    @Override
    public List<IChecker> getQuickChecks() {
        // Sort the quick checks
        ArrayList<IChecker> quickChecks = new ArrayList<>();
        quickChecks.add(new GenericExistenceChecker(genericParam1)); // Only 1 Generic because they are the same in the two configurations
        quickChecks.add(new ProductChecker(genericParam1.getProductUnit().getProductID()));
        quickChecks.add(new R07ProductUnitChecker(genericParam1.getProductUnit(), true));
        quickChecks.add(new R07ProductUnitChecker(genericParam2.getProductUnit(), false));
        return quickChecks;
    }

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

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

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

    @Override
    public String getTemplateLocation() {
        return "No Template needed for this report! it is automatically generated";
    }

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

    @Override
    public String getSpecifiedFileName() {
        return StringHelper.implode("_", "R07", getNameSheet());
    }

    /**
     * Returns the spreadsheet's name.
     *
     * @return the name
     */
    String getNameSheet() {
        ProductUnit productUnit1 = genericParam1.getProductUnit();
        String productId = productUnit1.getProductID();
        String unit1 = productUnit1.getUnitStr();
        String unit2 = genericParam2.getProductUnit().getUnitStr();
        String name;
        switch (genericParam1.getType()) {
            case GENERIC:
                name = StringHelper.implode("_", genericParam1.getGeneric(), productId, unit1, unit2);
                break;
            case GENERIC_ASSEMB:
                name = StringHelper.implode("_", genericParam1.getGenericAssemb(), productId, unit1, unit2);
                break;
            case ONLY_PRODUCT:
                name = StringHelper.implode("_", productId, unit1, unit2);
                break;
            default:
                name = "R07_UnsupportedGenericType_" + genericParam1.toString() + "_" + genericParam2.toString();
                break;
        }
        return name;
    }

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

    @Override
    public List<CriteriaValue> getLaunchData() {
        List<CriteriaValue> theCriteria = new ArrayList<>();
        // The Product is the same for the 2 configurations
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PRODUCT, genericParam1.getProductUnit().getProductID()));

        // Configuration 1
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT_CONFIGURATION_1, genericParam1.getProductUnit().getUnitStr()));
        if (GenericType.GENERIC.equals(genericParam1.getType())) {
            theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, genericParam1.getGeneric()));
        } else if (GenericType.GENERIC_ASSEMB.equals(genericParam1.getType())) {
            theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, genericParam1.getGenericAssemb()));
        }

        // Configuration 2
        theCriteria.add(new CriteriaValue(ReportCriteriaEnum.UNIT_CONFIGURATION_2, genericParam2.getProductUnit().getUnitStr()));
        return theCriteria;
    }

    @Override
    public IDataReportPreparator<ExecutionR07> getDataPreparator() {
        return new DataReportPreparatorR07();
    }

    @Override
    public AbstractExecutionReport<?, ?> cloneTemplateToExecution() {
        return new ExecutionR07(genericParam1, genericParam2);
    }

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