package com.capgemini.reports.definition.r21report;

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.R21Builder;
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.r21report.ExecutionR21.ReportDataR21;
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.DualGenerics;
import com.capgemini.reports.reports.parameters.EffectivityDate;
import com.capgemini.reports.reports.parameters.IChecker;
import com.capgemini.reports.reports.parameters.ProductUnit;
import com.capgemini.reports.reports.parameters.checker.*;
import lombok.AllArgsConstructor;
import lombok.Getter;

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

public class ExecutionR21 extends AbstractExecutionReport<ExecutionR21, ReportDataR21> {
  private static final long serialVersionUID = -2930624274965581115L;

  private static final PolicyLocation R21_POLICY_XML_LIGHT = PolicyLocation.make("R21_policy_light", "/xml/policies/r21report/R21_policy_light.xml");
  private static final PolicyLocation R21_POLICY_XML_FULL = PolicyLocation.make("R21_policy_full", "/xml/policies/r21report/R21_policy_full.xml");
  private static final String REPORT_REVISION_RULE = SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R21", DEFAULT_REVISION_RULE);
  private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R21);
  private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R21");

  private final ProductUnit productUnit;
  private final EffectivityDate effectivity;
  private final DualGenerics dualGeneric;

  public ExecutionR21(final ProductUnit aProductUnit, final DualGenerics aDualGeneric, final EffectivityDate anEffectivity) {
    super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE);
    productUnit = aProductUnit;
    dualGeneric = aDualGeneric;
    effectivity = anEffectivity;
  }

  @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()));
    theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC, dualGeneric.asGeneric().getID()));
    theCriteria.add(new CriteriaValue(ReportCriteriaEnum.GENERIC_ASSEMB, dualGeneric.asGenericAssemb().getID()));
    theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivity.formatAsInputCriteria()));
    return theCriteria;
  }

  @Override
  public List<IChecker> getQuickChecks() {
    // Sort the quick checks
    List<IChecker> quickChecks = new ArrayList<>();
    quickChecks.add(new GenericExistenceChecker(dualGeneric.asGeneric()));
    quickChecks.add(new GenericExistenceChecker(dualGeneric.asGenericAssemb()));
    quickChecks.add(new ProductChecker(productUnit.getProductID()));
    quickChecks.add(new ProductUnitChecker(productUnit));
    quickChecks.add(new EffectivityChecker(effectivity));
    return quickChecks;
  }

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

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

  @Override
  public List<IChecker> getLongChecks() {
    // Sort the Long checks
    List<IChecker> longChecks = new ArrayList<>();
    longChecks.add(new GenericConditionR21Checker(productUnit, dualGeneric));
    return longChecks;
  }

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

  @Override
  public String getSpecifiedFileName() {
    String separator = "-";
    return "R21-" + dualGeneric.asGeneric().getID() + separator + dualGeneric.asGenericAssemb().getID() +
        separator + productUnit.getProductID() + separator + productUnit.getUnit() + separator +
        effectivity.formatAsInputCriteria();
  }

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

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

  @Override
  public IDataReportPreparator<ExecutionR21> getDataPreparator() {
    return new DataReportPreparatorR21();
  }

  @Override
  public AbstractExecutionReport<?, ?> cloneTemplateToExecution() {
    return new ExecutionR21(productUnit, dualGeneric, effectivity);
  }

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

  public DualGenerics getDualGeneric() {
    return dualGeneric;
  }

  public ProductUnit getProductUnit() {
    return productUnit;
  }

  public EffectivityDate getEffectivity() {
    return effectivity;
  }

  /**
   * POJO container of all data required for this report.
   */
  @AllArgsConstructor
  @Getter
  public static class ReportDataR21 {
    private final BOMLineHolder topLineAssembly;
    private final BOMLineHolder topLineTechnical;
  }
}
