/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.fineract.infrastructure.reportmailingjob.service;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.dataqueries.domain.Report;
import org.apache.fineract.infrastructure.dataqueries.domain.ReportRepositoryWrapper;
import org.apache.fineract.infrastructure.dataqueries.service.ReadReportingService;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.FileSystemContentRepository;
import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException;
import org.apache.fineract.infrastructure.jobs.service.JobName;
import org.apache.fineract.infrastructure.report.provider.ReportingProcessServiceProvider;
import org.apache.fineract.infrastructure.report.service.ReportingProcessService;
import org.apache.fineract.infrastructure.reportmailingjob.ReportMailingJobConstants;
import org.apache.fineract.infrastructure.reportmailingjob.data.ReportMailingJobEmailAttachmentFileFormat;
import org.apache.fineract.infrastructure.reportmailingjob.data.ReportMailingJobEmailData;
import org.apache.fineract.infrastructure.reportmailingjob.data.ReportMailingJobPreviousRunStatus;
import org.apache.fineract.infrastructure.reportmailingjob.data.ReportMailingJobStretchyReportParamDateOption;
import org.apache.fineract.infrastructure.reportmailingjob.domain.ReportMailingJob;
import org.apache.fineract.infrastructure.reportmailingjob.domain.ReportMailingJobRepository;
import org.apache.fineract.infrastructure.reportmailingjob.domain.ReportMailingJobRepositoryWrapper;
import org.apache.fineract.infrastructure.reportmailingjob.domain.ReportMailingJobRunHistory;
import org.apache.fineract.infrastructure.reportmailingjob.domain.ReportMailingJobRunHistoryRepository;
import org.apache.fineract.infrastructure.reportmailingjob.util.ReportMailingJobDateUtil;
import org.apache.fineract.infrastructure.reportmailingjob.validation.ReportMailingJobValidator;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
import org.apache.fineract.useradministration.domain.AppUser;
import org.glassfish.jersey.internal.util.collection.MultivaluedStringMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.NonTransientDataAccessException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ReportMailingJobWritePlatformServiceImpl implements ReportMailingJobWritePlatformService {

    private static final Logger LOG = LoggerFactory.getLogger(ReportMailingJobWritePlatformServiceImpl.class);
    private final ReportRepositoryWrapper reportRepositoryWrapper;
    private final ReportMailingJobValidator reportMailingJobValidator;
    private final ReportMailingJobRepositoryWrapper reportMailingJobRepositoryWrapper;
    private final ReportMailingJobRepository reportMailingJobRepository;
    private final PlatformSecurityContext platformSecurityContext;
    private final ReportMailingJobEmailService reportMailingJobEmailService;
    private final ReadReportingService readReportingService;
    private final ReportingProcessServiceProvider reportingProcessServiceProvider;
    private final ReportMailingJobRunHistoryRepository reportMailingJobRunHistoryRepository;
    private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Autowired
    public ReportMailingJobWritePlatformServiceImpl(final ReportRepositoryWrapper reportRepositoryWrapper,
            final ReportMailingJobValidator reportMailingJobValidator,
            final ReportMailingJobRepositoryWrapper reportMailingJobRepositoryWrapper,
            final ReportMailingJobRepository reportMailingJobRepository, final PlatformSecurityContext platformSecurityContext,
            final ReportMailingJobEmailService reportMailingJobEmailService, final ReadReportingService readReportingService,
            final ReportMailingJobRunHistoryRepository reportMailingJobRunHistoryRepository,
            final ReportingProcessServiceProvider reportingProcessServiceProvider) {
        this.reportRepositoryWrapper = reportRepositoryWrapper;
        this.reportMailingJobValidator = reportMailingJobValidator;
        this.reportMailingJobRepositoryWrapper = reportMailingJobRepositoryWrapper;
        this.reportMailingJobRepository = reportMailingJobRepositoryWrapper.getReportMailingJobRepository();
        this.platformSecurityContext = platformSecurityContext;
        this.reportMailingJobEmailService = reportMailingJobEmailService;
        this.readReportingService = readReportingService;
        this.reportMailingJobRunHistoryRepository = reportMailingJobRunHistoryRepository;
        this.reportingProcessServiceProvider = reportingProcessServiceProvider;
    }

    @Override
    @Transactional
    public CommandProcessingResult createReportMailingJob(JsonCommand jsonCommand) {
        try {
            // validate the create request
            this.reportMailingJobValidator.validateCreateRequest(jsonCommand);

            final AppUser appUser = this.platformSecurityContext.authenticatedUser();

            // get the stretchy Report object
            final Report stretchyReport = this.reportRepositoryWrapper.findOneThrowExceptionIfNotFound(
                    jsonCommand.longValueOfParameterNamed(ReportMailingJobConstants.STRETCHY_REPORT_ID_PARAM_NAME));

            // create an instance of ReportMailingJob class from the JsonCommand
            // object
            final ReportMailingJob reportMailingJob = ReportMailingJob.newInstance(jsonCommand, stretchyReport, appUser);

            // save entity
            this.reportMailingJobRepository.saveAndFlush(reportMailingJob);

            return new CommandProcessingResultBuilder().withCommandId(jsonCommand.commandId()).withEntityId(reportMailingJob.getId())
                    .build();
        } catch (final JpaSystemException | DataIntegrityViolationException dve) {
            final Throwable throwable = dve.getMostSpecificCause();
            handleDataIntegrityIssues(jsonCommand, throwable, dve);

            return CommandProcessingResult.empty();
        }
    }

    @Override
    @Transactional
    public CommandProcessingResult updateReportMailingJob(Long reportMailingJobId, JsonCommand jsonCommand) {
        try {
            // validate the update request
            this.reportMailingJobValidator.validateUpdateRequest(jsonCommand);

            // retrieve the ReportMailingJob object from the database
            final ReportMailingJob reportMailingJob = this.reportMailingJobRepositoryWrapper
                    .findOneThrowExceptionIfNotFound(reportMailingJobId);

            final Map<String, Object> changes = reportMailingJob.update(jsonCommand);

            // get the recurrence rule string
            final String recurrence = reportMailingJob.getRecurrence();

            // get the next run LocalDateTime from the ReportMailingJob entity
            LocalDateTime nextRunDateTime = reportMailingJob.getNextRunDateTime();

            // check if the stretchy report id was updated
            if (changes.containsKey(ReportMailingJobConstants.STRETCHY_REPORT_ID_PARAM_NAME)) {
                final Long stretchyReportId = (Long) changes.get(ReportMailingJobConstants.STRETCHY_REPORT_ID_PARAM_NAME);
                final Report stretchyReport = this.reportRepositoryWrapper.findOneThrowExceptionIfNotFound(stretchyReportId);

                // update the stretchy report
                reportMailingJob.update(stretchyReport);
            }

            // check if the recurrence was updated
            if (changes.containsKey(ReportMailingJobConstants.RECURRENCE_PARAM_NAME)) {

                // go ahead if the recurrence is not null
                if (StringUtils.isNotBlank(recurrence)) {
                    // set the start LocalDateTime to the current tenant date time
                    LocalDateTime startDateTime = DateUtils.getLocalDateTimeOfTenant();

                    // check if the start LocalDateTime was updated
                    if (changes.containsKey(ReportMailingJobConstants.START_DATE_TIME_PARAM_NAME)) {
                        // get the updated start DateTime
                        startDateTime = reportMailingJob.getStartDateTime();
                    }

                    startDateTime = reportMailingJob.getStartDateTime();

                    // get the next recurring DateTime
                    final LocalDateTime nextRecurringDateTime = this.createNextRecurringDateTime(recurrence, startDateTime);

                    // update the next run time property
                    reportMailingJob.updateNextRunDateTime(nextRecurringDateTime);

                    // check if the next run LocalDateTime is not empty and the
                    // recurrence is empty
                } else if (StringUtils.isBlank(recurrence) && (nextRunDateTime != null)) {
                    // the next run LocalDateTime should be set to null
                    reportMailingJob.updateNextRunDateTime(null);
                }
            }

            if (changes.containsKey(ReportMailingJobConstants.START_DATE_TIME_PARAM_NAME)) {
                final LocalDateTime startDateTime = reportMailingJob.getStartDateTime();

                // initially set the next recurring date time to the new start
                // date time
                LocalDateTime nextRecurringDateTime = startDateTime;

                // ensure that the recurrence pattern string is not empty
                if (StringUtils.isNotBlank(recurrence)) {
                    // get the next recurring DateTime
                    nextRecurringDateTime = this.createNextRecurringDateTime(recurrence, startDateTime);
                }

                // update the next run time property
                reportMailingJob.updateNextRunDateTime(nextRecurringDateTime);
            }

            if (!changes.isEmpty()) {
                // save and flush immediately so any data integrity exception
                // can be handled in the "catch" block
                this.reportMailingJobRepository.saveAndFlush(reportMailingJob);
            }

            return new CommandProcessingResultBuilder().withCommandId(jsonCommand.commandId()).withEntityId(reportMailingJob.getId())
                    .with(changes).build();
        } catch (final JpaSystemException | DataIntegrityViolationException dve) {
            final Throwable throwable = dve.getMostSpecificCause();
            handleDataIntegrityIssues(jsonCommand, throwable, dve);

            return CommandProcessingResult.empty();
        }
    }

    @Override
    @Transactional
    public CommandProcessingResult deleteReportMailingJob(Long reportMailingJobId) {
        // retrieve the ReportMailingJob object from the database
        final ReportMailingJob reportMailingJob = this.reportMailingJobRepositoryWrapper
                .findOneThrowExceptionIfNotFound(reportMailingJobId);

        // delete the report mailing job by setting the isDeleted property to 1
        // and altering the name
        reportMailingJob.delete();

        // save the report mailing job entity
        this.reportMailingJobRepository.save(reportMailingJob);

        return new CommandProcessingResultBuilder().withEntityId(reportMailingJobId).build();
    }

    @Override
    @CronTarget(jobName = JobName.EXECUTE_REPORT_MAILING_JOBS)
    public void executeReportMailingJobs() throws JobExecutionException {
        final Collection<ReportMailingJob> reportMailingJobCollection = this.reportMailingJobRepository
                .findByIsActiveTrueAndIsDeletedFalse();

        for (ReportMailingJob reportMailingJob : reportMailingJobCollection) {
            final LocalDateTime localDateTimeOftenant = DateUtils.getLocalDateTimeOfTenant();
            final LocalDateTime nextRunDateTime = reportMailingJob.getNextRunDateTime();

            if (nextRunDateTime != null && nextRunDateTime.isBefore(localDateTimeOftenant)) {
                // get the emailAttachmentFileFormat enum object
                final ReportMailingJobEmailAttachmentFileFormat emailAttachmentFileFormat = ReportMailingJobEmailAttachmentFileFormat
                        .newInstance(reportMailingJob.getEmailAttachmentFileFormat());

                if (emailAttachmentFileFormat != null && emailAttachmentFileFormat.isValid()) {
                    final Report stretchyReport = reportMailingJob.getStretchyReport();
                    final String reportName = (stretchyReport != null) ? stretchyReport.getReportName() : null;
                    final StringBuilder errorLog = new StringBuilder();
                    final Map<String, String> validateStretchyReportParamMap = this.reportMailingJobValidator
                            .validateStretchyReportParamMap(reportMailingJob.getStretchyReportParamMap());
                    MultivaluedMap<String, String> reportParams = new MultivaluedStringMap();

                    if (validateStretchyReportParamMap != null) {
                        Iterator<Map.Entry<String, String>> validateStretchyReportParamMapEntries = validateStretchyReportParamMap
                                .entrySet().iterator();

                        while (validateStretchyReportParamMapEntries.hasNext()) {
                            Map.Entry<String, String> validateStretchyReportParamMapEntry = validateStretchyReportParamMapEntries.next();
                            String key = validateStretchyReportParamMapEntry.getKey();
                            String value = validateStretchyReportParamMapEntry.getValue();

                            if (StringUtils.containsIgnoreCase(key, "date")) {
                                ReportMailingJobStretchyReportParamDateOption reportMailingJobStretchyReportParamDateOption = ReportMailingJobStretchyReportParamDateOption
                                        .newInstance(value);

                                if (reportMailingJobStretchyReportParamDateOption.isValid()) {
                                    value = ReportMailingJobDateUtil.getDateAsString(reportMailingJobStretchyReportParamDateOption);
                                }
                            }

                            reportParams.add(key, value);
                        }
                    }

                    // generate the report output stream, method in turn call
                    // another that sends the file to the email recipients
                    this.generateReportOutputStream(reportMailingJob, emailAttachmentFileFormat, reportParams, reportName, errorLog);

                    // update the previous run time, next run time, status,
                    // error log properties
                    this.updateReportMailingJobAfterJobExecution(reportMailingJob, errorLog, localDateTimeOftenant);
                }
            }
        }
    }

    /**
     * update the report mailing job entity after job execution
     *
     * @param reportMailingJob
     *            -- the report mailing job entity
     * @param errorLog
     *            -- StringBuilder object containing the error log if any
     * @param jobStartDateTime
     *            -- the start LocalDateTime of the job
     *
     **/
    private void updateReportMailingJobAfterJobExecution(final ReportMailingJob reportMailingJob, final StringBuilder errorLog,
            final LocalDateTime jobStartDateTime) {
        final String recurrence = reportMailingJob.getRecurrence();
        final LocalDateTime nextRunDateTime = reportMailingJob.getNextRunDateTime();
        ReportMailingJobPreviousRunStatus reportMailingJobPreviousRunStatus = ReportMailingJobPreviousRunStatus.SUCCESS;

        reportMailingJob.updatePreviousRunErrorLog(null);

        if (errorLog != null && errorLog.length() > 0) {
            reportMailingJobPreviousRunStatus = ReportMailingJobPreviousRunStatus.ERROR;
            reportMailingJob.updatePreviousRunErrorLog(errorLog.toString());
        }

        reportMailingJob.increaseNumberOfRunsByOne();
        reportMailingJob.updatePreviousRunStatus(reportMailingJobPreviousRunStatus.getValue());
        reportMailingJob.updatePreviousRunDateTime(reportMailingJob.getNextRunDateTime());

        // check if the job has a recurrence pattern, if not deactivate the job.
        // The job will only run once
        if (StringUtils.isEmpty(recurrence)) {
            // deactivate job
            reportMailingJob.deactivate();

            // job will only run once, no next run time
            reportMailingJob.updateNextRunDateTime(null);
        } else if (nextRunDateTime != null) {
            final LocalDateTime nextRecurringDateTime = this.createNextRecurringDateTime(recurrence, nextRunDateTime);

            // finally update the next run date time property
            reportMailingJob.updateNextRunDateTime(nextRecurringDateTime);
        }

        // save the ReportMailingJob entity
        this.reportMailingJobRepository.save(reportMailingJob);

        // create a new report mailing job run history entity
        this.createReportMailingJobRunHistroryAfterJobExecution(reportMailingJob, errorLog, jobStartDateTime,
                reportMailingJobPreviousRunStatus.getValue());
    }

    /**
     * create the next recurring LocalDateTime from recurrence pattern, start LocalDateTime and current DateTime
     *
     * @param recurrencePattern
     * @param startDateTime
     * @return LocalDateTime object
     */
    private LocalDateTime createNextRecurringDateTime(final String recurrencePattern, final LocalDateTime startDateTime) {
        LocalDateTime nextRecurringDateTime = null;

        // the recurrence pattern/rule cannot be empty
        if (StringUtils.isNotBlank(recurrencePattern) && startDateTime != null) {
            final LocalDateTime nextDayLocalDate = startDateTime.plus(Duration.ofDays(1));
            nextRecurringDateTime = CalendarUtils.getNextRecurringDate(recurrencePattern, startDateTime, nextDayLocalDate);
        }

        return nextRecurringDateTime;
    }

    /**
     * create a new report mailing job run history entity after job execution
     *
     * @param reportMailingJob
     *            -- the report mailing job entity
     * @param errorLog
     *            -- StringBuilder object containing the error log if any
     * @param jobStartDateTime
     *            -- the start LocalDateTime of the job
     * @param jobRunStatus
     *            -- the status of the job (success/error)
     *
     **/
    private void createReportMailingJobRunHistroryAfterJobExecution(final ReportMailingJob reportMailingJob, final StringBuilder errorLog,
            final LocalDateTime jobStartDateTime, final String jobRunStatus) {
        final LocalDateTime jobEndDateTime = DateUtils.getLocalDateTimeOfTenant();
        final String errorLogToString = (errorLog != null) ? errorLog.toString() : null;
        final ReportMailingJobRunHistory reportMailingJobRunHistory = ReportMailingJobRunHistory.newInstance(reportMailingJob,
                jobStartDateTime, jobEndDateTime, jobRunStatus, null, errorLogToString);

        this.reportMailingJobRunHistoryRepository.save(reportMailingJobRunHistory);
    }

    /**
     * Handle any SQL data integrity issue
     *
     * @param jsonCommand
     *            -- JsonCommand object
     * @param dve
     *            -- data integrity exception object
     *
     **/
    private void handleDataIntegrityIssues(final JsonCommand jsonCommand, final Throwable realCause,
            final NonTransientDataAccessException dve) {

        if (realCause.getMessage().contains(ReportMailingJobConstants.NAME_PARAM_NAME)) {
            final String name = jsonCommand.stringValueOfParameterNamed(ReportMailingJobConstants.NAME_PARAM_NAME);
            throw new PlatformDataIntegrityException("error.msg.report.mailing.job.duplicate.name",
                    "Report mailing job with name `" + name + "` already exists", ReportMailingJobConstants.NAME_PARAM_NAME, name);
        }

        LOG.error("Error occured.", dve);

        throw new PlatformDataIntegrityException("error.msg.charge.unknown.data.integrity.issue",
                "Unknown data integrity issue with resource: " + realCause.getMessage());
    }

    /**
     * generate the report output stream
     *
     * @param reportMailingJob
     * @param emailAttachmentFileFormat
     * @param reportParams
     * @param reportName
     * @param errorLog
     * @return the error log StringBuilder object
     */
    private StringBuilder generateReportOutputStream(final ReportMailingJob reportMailingJob,
            final ReportMailingJobEmailAttachmentFileFormat emailAttachmentFileFormat, final MultivaluedMap<String, String> reportParams,
            final String reportName, final StringBuilder errorLog) {

        try {
            final boolean isSelfServiceUserReport = false;
            final String reportType = this.readReportingService.getReportType(reportName, isSelfServiceUserReport, false);
            final ReportingProcessService reportingProcessService = this.reportingProcessServiceProvider
                    .findReportingProcessService(reportType);

            if (reportingProcessService != null) {
                final Response processReport = reportingProcessService.processRequest(reportName, reportParams);
                final Object reponseObject = (processReport != null) ? processReport.getEntity() : null;

                if (reponseObject != null && reponseObject.getClass().equals(ByteArrayOutputStream.class)) {
                    final ByteArrayOutputStream byteArrayOutputStream = ByteArrayOutputStream.class.cast(reponseObject);
                    final String fileLocation = FileSystemContentRepository.FINERACT_BASE_DIR + File.separator + "";
                    final String fileNameWithoutExtension = fileLocation + File.separator + reportName;

                    // check if file directory exists, if not create directory
                    if (!new File(fileLocation).isDirectory()) {
                        new File(fileLocation).mkdirs();
                    }

                    if ((byteArrayOutputStream == null) || byteArrayOutputStream.size() == 0) {
                        errorLog.append("Report processing failed, empty output stream created");
                    } else if ((errorLog != null && errorLog.length() == 0) && (byteArrayOutputStream.size() > 0)) {
                        final String fileName = fileNameWithoutExtension + "." + emailAttachmentFileFormat.getValue();

                        // send the file to email recipients
                        this.sendReportFileToEmailRecipients(reportMailingJob, fileName, byteArrayOutputStream, errorLog);
                    }
                } else {
                    errorLog.append("Response object entity is not equal to ByteArrayOutputStream ---------- ");
                }
            } else {
                errorLog.append(ReportingProcessServiceProvider.SERVICE_MISSING + reportType);
            }
        } catch (Exception e) {
            errorLog.append("The ReportMailingJobWritePlatformServiceImpl.generateReportOutputStream method threw an Exception: " + e
                    + " ---------- ");
        }

        return errorLog;
    }

    /**
     * send report file to email recipients
     *
     * @param reportMailingJob
     * @param fileName
     * @param byteArrayOutputStream
     * @param errorLog
     */
    private void sendReportFileToEmailRecipients(final ReportMailingJob reportMailingJob, final String fileName,
            final ByteArrayOutputStream byteArrayOutputStream, final StringBuilder errorLog) {
        final Set<String> emailRecipients = this.reportMailingJobValidator.validateEmailRecipients(reportMailingJob.getEmailRecipients());

        try {
            final File file = new File(fileName);
            final FileOutputStream outputStream = new FileOutputStream(file);
            byteArrayOutputStream.writeTo(outputStream);

            for (String emailRecipient : emailRecipients) {
                final ReportMailingJobEmailData reportMailingJobEmailData = new ReportMailingJobEmailData(emailRecipient,
                        reportMailingJob.getEmailMessage(), reportMailingJob.getEmailSubject(), file);

                this.reportMailingJobEmailService.sendEmailWithAttachment(reportMailingJobEmailData);
            }

            outputStream.close();

        } catch (IOException e) {
            errorLog.append("The ReportMailingJobWritePlatformServiceImpl.sendReportFileToEmailRecipients method threw an IOException "
                    + "exception: " + e + " ---------- ");
        }
    }
}
