package com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r15report;

import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.framework.common.StringHelper;
import com.capgemini.framework.common.TeamcenterDateFormatter;
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.R15Builder;
import com.capgemini.reports.builder.ReportBuilder;
import com.capgemini.reports.definition.r15r16r17reports.AbstractExecutionR15R16R17;
import com.capgemini.reports.definition.r15r16r17reports.r15r17reports.AbstractExecutionR15R17;
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.IChecker;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * This class controls the execution of a R15 report.
 */
@Getter
@Slf4j
@Setter(value = AccessLevel.PROTECTED)
public class ExecutionR15 extends AbstractExecutionR15R17<ExecutionR15> {

    private static final int TO_SECONDS = 1000;

    private static final String PDF_EXTENSION = ".pdf";

    private static final String ENGLISH_DATASET = "_ENG";

    private static final String FICHE_ARTICLE_REALISATION = "FA_Real";

    private static final long serialVersionUID = -4306188095393629328L;

    private static final String FILE_SEPARATOR = "_";

    // Policies
    private static final PolicyLocation R15_POLICY_XML_FULL = PolicyLocation.make("R15_policy_full", "/xml/policies/r15report/R15_policy_full.xml");
    private static final PolicyLocation R15_POLICY_XML_LIGHT =
            PolicyLocation.make("R15_policy_light", "/xml/policies/r15report/R15_policy_light.xml");
    // Priority parameter
    private static final int REPORT_PRIORITY = SettingsHelper.getPriority(ReportEnum.REPORT_R15);
    // Revision rule parameter
    private static final String REPORT_REVISION_RULE =
            SettingsHelper.getPropertyWithDefaultValue("common.bom.revisionRule.REPORT_R15", DEFAULT_REVISION_RULE);
    // Launch type parameter
    private static final ReportLaunchTypeEnum REPORT_LAUNCH_TYPE = ReportLaunchTypeEnum.getReportLaunchType("common.launch.launchType.REPORT_R15");
    // Data gathered
    private String frontiereAvion;
    private String frontiereCooperant;

    /**
     * Constructor.
     *
     * @param partId       {@link String} - the ID of the Part
     * @param partRevision {@link String} - the Revision of the Part
     * @param language     {@link String} - the language selected by the user
     */
    public ExecutionR15(final String partId, final String partRevision, final String language) {
        super(partId, partRevision, language, REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE);
    }

    /**
     * Constructor for R15 in French.
     *
     * @param partId       {@link String} - the ID of the Part
     * @param partRevision {@link String} - the Revision of the Part
     */
    public ExecutionR15(final String partId, final String partRevision) {
        super(partId, partRevision, AbstractExecutionR15R16R17.FRENCH_LANGUAGE, REPORT_PRIORITY, REPORT_REVISION_RULE, REPORT_LAUNCH_TYPE);
    }

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

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

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

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

    @Override
    public ReportEnum getReportIdentifier() {
        return wkf ? ReportEnum.REPORT_W15 : ReportEnum.REPORT_R15;
    }

    @Override
    public String getSpecifiedFileName() {
        StringBuilder filename =
                new StringBuilder(itemId).append(FILE_SEPARATOR).append(itemRevision).append(FILE_SEPARATOR).append(FICHE_ARTICLE_REALISATION);
        if (!isFrench()) {
            filename.append(ENGLISH_DATASET);
        }
        return filename.toString();
    }

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

    @Override
    public IDataReportPreparator<ExecutionR15> getDataPreparator() {
        return new DataReportPreparatorR15();
    }

    @Override
    public AbstractExecutionReport<?, ?> cloneTemplateToExecution() {
        return new ExecutionR15(itemId, itemRevision, frenchInput);
    }

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

    // ******************** Methods for Automatic Workflow execution **********************

    /**
     * The dataset name (if the the report is executed by a workflow).
     *
     * @return the dataset name
     */
    String getDatasetName() {
        return StringHelper.implode(FILE_SEPARATOR, getItemId(), getItemRevision(), FICHE_ARTICLE_REALISATION);
    }

    /**
     * The filename in the dataset (if the the report is executed by a workflow).
     *
     * @return the file name (with extension)
     */
    String getDatasetFileNameWithExtension() {
        Date startDate;
        try {
            startDate = new SimpleDateFormat(TeamcenterDateFormatter.DD_MM_YYYY_HH_MM_SS).parse(getStartTime());
        } catch (ParseException e) {
            log.warn("Unable to parse stored start date, generating a date using NOW for W15 " + getReportTechnicalUid(), e);
            startDate = new Date();
        }
        String dateStr = new SimpleDateFormat(TeamcenterDateFormatter.YYYYMMDD).format(startDate);
        long timestamp = startDate.getTime() / TO_SECONDS;
        String timestampStr = String.valueOf(timestamp);
        String bareFilename = StringHelper.implode(FILE_SEPARATOR, getItemId(), getItemRevision(), FICHE_ARTICLE_REALISATION, dateStr, timestampStr);
        return bareFilename + PDF_EXTENSION;
    }

    String getOriginalDatasetFileNameWithExtension() {
        return getFileNameOnDisc() + PDF_EXTENSION;
    }
}
