package com.capgemini.reports.definition.r26report;

import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.framework.common.TeamcenterDateFormatter;
import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes;
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.builder.R26Builder;
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.r26report.ExecutionR26.ReportDataR26;
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.IChecker;
import com.capgemini.reports.reports.parameters.checker.ObjectTypeChecker;
import lombok.Getter;

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

/**
 * Class responsible for executing a R26 report.
 */
@Getter
public class ExecutionR26 extends AbstractExecutionReport<ExecutionR26, ReportDataR26> {

  private static final long serialVersionUID = -8662335546561586221L;

  // Policies parameters
  private static final PolicyLocation R26_POLICY_XML_LIGHT = PolicyLocation.make("R26_policy_light", "/xml/policies/r26report/R26_policy_light.xml");
  private static final PolicyLocation R26_POLICY_XML_FULL = PolicyLocation.make("R26_policy_full", "/xml/policies/r26report/R26_policy_full.xml");

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

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

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

  // Configuration
  private static final String SEPARATOR = "-";
  private static final String PATTERN_DATE = "yyyy-MM-dd";

  // Raw input parameters
  private final String component;
  private final EffectivityDate effectivityDate;

  /**
   * Constructor.
   *
   * @param component       {@link String} - the component
   * @param effectivityDate {@link EffectivityDate} - the effectivity
   */
  public ExecutionR26(final String component, final EffectivityDate effectivityDate) {
    super(REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE);
    this.component = component;
    this.effectivityDate = effectivityDate;
  }

  @Override
  public List<CriteriaValue> getLaunchData() {
    List<CriteriaValue> theCriteria = new ArrayList<>();
    theCriteria.add(new CriteriaValue(ReportCriteriaEnum.PART_ID, component));
    theCriteria.add(new CriteriaValue(ReportCriteriaEnum.EFFECTIVITY_DATE, effectivityDate.formatAsInputCriteria()));
    theCriteria.add(new CriteriaValue(ReportCriteriaEnum.REVISION_RULE, this.revisionRule));
    return theCriteria;
  }

  @Override
  public List<IChecker> getQuickChecks() {
    ArrayList<IChecker> quickChecks = new ArrayList<>();
    quickChecks.add(new ObjectTypeChecker(component, SnecmaObjectTypes.ALTERNATE, SnecmaObjectTypes.DET,
      SnecmaObjectTypes.PART_AERO, SnecmaObjectTypes.PART_ASSEMB, SnecmaObjectTypes.PART_MAT,
      SnecmaObjectTypes.PART_NO_AERO, SnecmaObjectTypes.STANDARD));
    return quickChecks;
  }

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

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

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

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

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

  /**
   * Format file expected : R26-"Composant"-"Date effectivté".XLSX
   */
  @Override
  public String getSpecifiedFileName() {
    StringBuilder filename = new StringBuilder("R26-");
    filename.append(component).append(SEPARATOR);
    filename.append(TeamcenterDateFormatter.formatCalendarToPattern(Calendar.getInstance(), PATTERN_DATE));
    return filename.toString();
  }

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

  @Override
  public IDataReportPreparator<ExecutionR26> getDataPreparator() {
    return new DataReportPreparatorR26();
  }

  @Override
  public AbstractExecutionReport<?, ?> cloneTemplateToExecution() {
    return new ExecutionR26(component, effectivityDate);
  }

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


  /**
   * POJO container of all data required for this report.
   */
  public static class ReportDataR26 {
    private final List<R26BomLine> r26BomLines;

    private boolean isStandard = false;

    public boolean isStandard() {
      return isStandard;
    }

    public void setStandard(boolean standard) {
      isStandard = standard;
    }

    protected ReportDataR26(final List<R26BomLine> r26BomLines) {
      this.r26BomLines = r26BomLines;
    }

    public List<R26BomLine> getR26BomLines() {
      return r26BomLines;
    }
  }
}
