package com.capgemini.reports.execution.strategies;

import com.capgemini.reports.ReportLaunchTypeEnum;
import com.capgemini.reports.execution.actions.*;
import lombok.EqualsAndHashCode;

/**
 * Strategy for reports launched automatically, via a workflow. <br>
 * In this strategy, no email are sent except on error cases, in which case a re-launch URL is provided.
 */
@EqualsAndHashCode(callSuper = true)
public class AutomaticExecutionStrategy extends AbstractExecutionStrategy {

    private static final long serialVersionUID = -476263626956824427L;

    /**
     * Prepares a strategy for automatic execution.
     * @param requestURL a URL that allows the process to be executed again in case of an error
     */
    public AutomaticExecutionStrategy(String requestURL) {
        super(makePreAction(new DoNothingAction()), makePostAction(new DoNothingAction()), makeErrorActionPlan(requestURL));
    }

    /**
     * Prepares a strategy for automatic execution.
     * @param requestURL a URL that allows the process to be executed again in case of an error
     * @param specializedPreAction a special action to perform before anything is done on this report
     * @param specializedPostAction a special action to perform right after the report has been generated
     */
    public AutomaticExecutionStrategy(String requestURL, final IPreExecutionStep specializedPreAction,
            final IPostExecutionStep specializedPostAction) {
        super(makePreAction(specializedPreAction), makePostAction(specializedPostAction), makeErrorActionPlan(requestURL));
    }

    /**
     * Pre-execution action for reports launched automatically by workflow.
     * <ol>
     * <li>Update AbstractExecutionReport state (startDate).</li>
     * <li>Register report execution start in the DB.</li>
     * <li>Log report Start event i special log file</li>
     * <li>log effective start in technical log</li>
     * </ol>
     * Note: no email sent in normal execution flow
     */
    private static CompositePreAction makePreAction(final IPreExecutionStep specializedPreAction) {
        // Be sure to NOT include mails of any kind in normal report execution actions
        return new CompositePreAction(specializedPreAction, new UpdateReportAction(), new UpdateReportInDbAction(), new LoggingAction());
    }

    /**
     * post-execution action for reports launched automatically by workflow.
     * <ol>
     * <li>Update AbstractExecutionReport state (endDate).</li>
     * <li>Register report execution end in the DB.</li>
     * <li>Send end email to report owners (include the location where the report can be retrieved as a download link)</li>
     * <li>log effective end in technical log</li>
     * </ol>
     * 
     * @param report the report which has been completed
     */
    private static CompositePostAction makePostAction(final IPostExecutionStep specializedPostAction) {
        // Be sure to NOT include mails of any kind in normal report execution actions
        return new CompositePostAction(specializedPostAction, new UpdateReportAction(), new UpdateReportInDbAction(), new LoggingAction());
    }

    private static IErrorExecutionStep makeErrorActionPlan(String requestURL) {
        return new CompositeErrorAction(new UpdateReportAction(), new UpdateReportInDbAction(), new LoggingAction(),
                new ReLaunchEmailAction(requestURL));
    }

    @Override
    public ReportLaunchTypeEnum getLaunchType() {
        return ReportLaunchTypeEnum.AUTOMATIC;
    }

}
