package gov.va.vinci.dart.wf2;

import static org.apache.commons.collections.CollectionUtils.isEmpty;

import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import gov.va.vinci.dart.common.exception.ObjectNotFoundException;
import gov.va.vinci.dart.AppPropertiesProcessor;
import gov.va.vinci.dart.DartController;
import gov.va.vinci.dart.biz.DartRequest;
import gov.va.vinci.dart.biz.DataSource;
import gov.va.vinci.dart.biz.Group;
import gov.va.vinci.dart.biz.GroupMailbox;
import gov.va.vinci.dart.biz.Participant;
import gov.va.vinci.dart.biz.Person;
import gov.va.vinci.dart.biz.PreparatoryRequest;
import gov.va.vinci.dart.biz.Request;
import gov.va.vinci.dart.biz.RequestStatus;
import gov.va.vinci.dart.biz.RequestWorkflow;
import gov.va.vinci.dart.biz.Review;
import gov.va.vinci.dart.biz.Role;
import gov.va.vinci.dart.mail.MailManager;
import gov.va.vinci.dart.service.DartObjectFactory;

/**
 * The Class EmailUtils.
 */
public class EmailUtils {

    /** The Constant LOG. */
    private static final Logger LOG = LogManager.getLogger(EmailUtils.class);
    /**
     * Returns a string containing the link to the DART dash board.
     *
     * @param body
     *            the body
     */
    public static void appendDartIndexPageInstructions(StringBuffer body) {
        LOG.debug("Appending Dart Index Page Instructions");
        if (body != null) {

            final String indexPage = DartController.getIndexPage();
            if (indexPage != null) {
                if (indexPage.length() > 1) {
                    body.append("\r\rYou can review this request by clicking on the following link: ");
                    body.append(indexPage);
                }
            }
        }
    }

    /**
     * Append request type.
     *
     * @param request
     *            the request
     * @param subject
     *            the subject
     */
    private static void appendRequestType(final Request request, StringBuffer subject) {
        LOG.debug("Appending Request Type");
        subject.append(" - " + request.getRequestTypeString() + " - ");
    }
    

    /**
     * Append generic request attributes.
     *
     * @param request
     *            the request
     * @param fullName
     *            the full name
     * @param body
     *            the body
     */
    public static void appendGenericRequestAttributes(final Request request, StringBuffer body) {
        LOG.debug("Appending Generic Request Attributes");
        appendStudyName(request, body);
        appendPrincipalInvestigator(request, body);
        appendDartTrackingNumber(request, body);

    }

    /**
     * Append dart request attributes.
     *
     * @param request
     *            the request
     * @param body
     *            the initial nds body
     */
    public static void appendDartRequestAttributes(final Request request, StringBuffer body) {
        LOG.debug("Appending DART Request Attributes");
        appendStudyName(request, body);
        appendIRBNumber(request, body);
        appendStudyStartAndEndDate(request, body);
        appendIRBExpirationDate(request, body);
        appendDartTrackingNumber(request, body);
    }

    /**
     * Append dart request attributes.
     *
     * @param request
     *            the request
     * @param body
     *            the initial nds body
     */
    public static void appendPreparatoryRequestAttributes(final Request request, StringBuffer body) {
        LOG.debug("Appending Preparatory Request Attributes");
        appendStudyName(request, body);
        appendExpectedIRBSubmissionDate(request, body);
        appendDartTrackingNumber(request, body);

    }

    private static void appendDartTrackingNumber(final Request request, StringBuffer body) {
        LOG.debug("Appending Dart Tracking Number");
        if (request != null) {
            body.append("\r\rDART Tracking Number: ").append(request.getTrackingNumber());
        }
    }
    


    private static void appendIRBNumber(final Request request, StringBuffer body) {
        LOG.debug("Appending IRB Number");
        if (request != null) {
            body.append("\rIRB Number: ").append(request.getIrbNumber());
        }
    }

    private static void appendIRBExpirationDate(final Request request, StringBuffer body) {
        LOG.debug("Appending IRB Expiration Date");
        if (request != null && request.getActivity() != null) {
            body.append("\rIRB Expiration Date: ").append(request.getActivity().getEndDate());
        }
    }

    public static void appendInitiatedBy(final Request request, StringBuffer initialNDSBody) {
        LOG.debug("Appending InitiatedBy");
        if (request != null) {
            initialNDSBody.append("\r\rInitiated By: ").append(request.getCreatedBy());
        }
    }

    /**
     * Append principal investigator.
     *
     * @param request
     *            the request
     * @param body
     *            the body
     */
    private static void appendPrincipalInvestigator(final Request request, StringBuffer body) {
        LOG.debug("Appending PrincipalInvestigator");
        if (request != null) {
            body.append("\r\rPrincipal Investigator: ");
            body.append(getPrincipalInvestigatorsLastName(request.getPrincipalInvestigator()));
        }
    }
    

    /**
     * Gets the principal investigators last name.
     *
     * @param principalInvestigatorFullName
     *            the principal investigator full name
     * @return the principal investigators last name
     */
    private static String getPrincipalInvestigatorsLastName(String principalInvestigatorFullName) {
        String[] strArray = principalInvestigatorFullName.toString().split(" ");
        String[] lastName = strArray[0].toString().split(",");
        return lastName[0];
    }

    private static void appendStudySlashProtocolName(final Request request, StringBuffer body) {
        LOG.debug("Appending Study/ProtocolName");
        if (request != null && request.getActivity() != null) {
            body.append("\r*    Study/Protocol Name: " + request.getActivity().getOfficialName());
        }
    }

    private static void appendStudyName(final Request request, StringBuffer body) {
        LOG.debug("Appending Study Name");
        if (request != null && request.getActivity() != null) {
            body.append("\r\rStudy Name: ").append(request.getActivity().getOfficialName());

        }
    }
    


    private static void appendStudyStartAndEndDate(final Request request, StringBuffer body) {
        LOG.debug("Appending Study Start and End Date");
        if (request != null) {
            if (request.getActivity() != null) {
                body.append("\rStudy Start Date: ").append(request.getActivity().getStartDate());
                body.append("\rStudy End Date: ").append(request.getActivity().getEndDate());
            }
        }
    }

    private static void appendExpectedIRBSubmissionDate(final Request request, StringBuffer body) {
        LOG.debug("Appending Expected IRB Submission Date");
        if (request != null) {
            if (PreparatoryRequest.class.isAssignableFrom(request.getClass())) {
                body.append("\r\rExpected IRB Submission Date: ")
                        .append(((PreparatoryRequest) request).getExpectedIRBSubmissionDate());

            }
        }
    }

    /**
     * Send email to method.
     *
     * @param emailAddress
     *            the email address
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToEmailAddress(final String emailAddress, final String subject, final String body) {

        MailManager mailManager = DartObjectFactory.getInstance().getMailManager();
        if (mailManager != null) {

            mailManager.sendPlainMailToEmailDest(emailAddress, subject, body);

        }
    }

    public static void sendEmailToUserLoginId(final String userLoginId, final String subject, final String body) {

        MailManager mailManager = DartObjectFactory.getInstance().getMailManager();
        if (mailManager != null) {

            mailManager.sendPlainMailToEmailDest(userLoginId, subject, body);

        }
    }

    /**
     * Sends this email to every member with the group association in DART and the Groups shared email box.
     *
     * @param group
     *            the group
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToGroupAndGroupMailBox(final Group group, final String subject, final String body) {

        Group.initialize();

        if (group != null) {

            sendEmailToGroup(group, subject, body);
            sendEmailToGroupMailBox(group, subject, body);
        }
    }
    
    
    /**
     * Send email to group and group mail box.
     *
     * @param groupList the group list
     * @param subject the subject
     * @param body the body
     */
    public static void sendEmailToGroupAndGroupMailBox(final List<Group> groupList, final String subject, final String body) {

        Group.initialize();

        if (!isEmpty(groupList)) {
            for (Group group : groupList) {
                sendEmailToGroup(group, subject, body);
                sendEmailToGroupMailBox(group, subject, body);
            }
        }
    }

    /**
     * Sends this email to every member of with the group association in DART.
     *
     * @param group
     *            the group
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToGroup(final Group group, final String subject, final String body) {

        Group.initialize();
        if (group != null) {
            List<Person> personList = Person.listByGroupAndNotifications(group.getId());
            sendEmailToPersonList(personList, subject, body);
        }
    }

    /**
     * Sends this email to the Groups shared email box.
     *
     * @param group
     *            the group
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToGroupMailBox(final Group group, final String subject, final String body) {

        Group.initialize();

        if (group != null) {
            if (group.getGroupMailbox() != null) {
                sendEmailToGroupMailBox(group.getGroupMailbox(), subject, body);
            }
        }
    }

    /**
     * Send email to group mail box.
     *
     * @param groupMailbox
     *            the group mailbox
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToGroupMailBox(final GroupMailbox groupMailbox, final String subject, final String body) {

        Group.initialize();

        if (groupMailbox != null) {
            MailManager mailManager = DartObjectFactory.getInstance().getMailManager();
            if (mailManager != null) {
                if (groupMailbox.getNotification()) {
                    if (groupMailbox.getEmail() != null && groupMailbox.getEmail().trim().isEmpty() == false) {
                        mailManager.sendPlainMailToEmailDest(groupMailbox.getEmail(), subject.toString(), body.toString());
                    }
                }
            }
        }
    }

    /**
     * Sends this email (subject and body) to every person in this group who has this role.
     *
     * @param group
     *            the group
     * @param role
     *            the role
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToGroupAndRole(final Group group, final Role role, final String subject, final String body) {

        Group.initialize();
        Role.initialize();

        if (group != null && role != null) {

            List<Person> personList = Person.listAllWithRoleAndGroupAndNotifications(role.getId(), group.getId());

            sendEmailToPersonList(personList, subject, body);

            sendEmailToGroupMailBox(group, subject, body);

        }
    }

    /**
     * Send email to person list method.
     *
     * @param personList
     *            the person list
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToPersonList(List<Person> personList, final String subject, final String body) {
        if (personList != null && personList.size() > 0) {
            for (Person person : personList) {
                sendEmailToPerson(person, subject, body);
            }
        }
    }

    /**
     * Send email to person method will take the persons name to upper-case.
     *
     * @param person
     *            the person
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToPerson(Person person, final String subject, final String body) {
        MailManager mailManager = DartObjectFactory.getInstance().getMailManager();
        if (mailManager != null) {
            mailManager.sendPlainMail(person.getName().toUpperCase(), subject, body);
        }
    }

    /**
     * Sends this email to every person with the NDS group or role association and the NDS group shared mailbox.
     *
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToNDSAdminList(final String subject, final String body) {

        Role.initialize();
        Group.initialize();

        List<Person> personList = Person.listAllWithRoleAndGroupAndNotifications(Role.NDS_ADMIN.getId(), Group.NDS.getId());
        sendEmailToPersonList(personList, subject, body);

        GroupMailbox groupMailbox = Group.NDS.getGroupMailbox();
        sendEmailToGroupMailBox(groupMailbox, subject, body);
    }

    /**
     * Sends this email to every person with the super-user DART Admin role and the Dart Admin group shared mailbox.
     *
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToDARTAdminList(final String subject, final String body) {

        Role.initialize();
        Group.initialize();

        List<Person> persons =
                Person.listAllWithRoleAndGroupAndNotifications(Role.SUPER_USER.getId(), Group.DART_ADMIN.getId());
        sendEmailToPersonList(persons, subject, body);

        GroupMailbox groupMailbox = Group.DART_ADMIN.getGroupMailbox();
        sendEmailToGroupMailBox(groupMailbox, subject, body);

    }

    /**
     * Sends this email to the VINCI Data Managers email address. This email address is pulled from the application property
     * files.
     *
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToVINCIDataManagersEmail(final String subject, final String body) {

        sendEmailToEmailAddress(AppPropertiesProcessor.getVINCIDataManagersEmail(), subject, body);

    }

    /**
     * Send email to participant.
     *
     * @param participant
     *            the participant
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToParticipant(Participant participant, final String subject, final String body) {

        MailManager mailManager = DartObjectFactory.getInstance().getMailManager();
        if (mailManager != null) {

            if (participant != null && participant.getPerson() != null && participant.getPerson().getName() != null) {
                if (participant.getNotification()) {
                    mailManager.sendPlainMail(participant.getPerson().getName().toUpperCase(), subject, body);
                }
            }
        }
    }

    /**
     * Send email to participants.
     *
     * @param participants
     *            the participants
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sendEmailToParticipants(Set<Participant> participants, final String subject, final String body) {

        if (participants != null && participants.size() > 0) {

            for (Participant participant : participants) {
                sendEmailToParticipant(participant, subject, body);
            }
        }
    }

    /**
     * Send expected IRB submission date has expired email.
     *
     * @param request
     *            the request
     */
    public static void sendExpectedIRBSubmissionDateHasExpiredEmail(Request request) {
        Set<Participant> participants = request.getParticipants();
        String subject = createExpectedIRBSubmissionDateEmailSubject(request);
        String body = createExpectedIRBSubmissionDateEmailBody(request);
        sendEmailToParticipants(participants, subject, body);
        sendEmailToDARTAdminList(subject, body);
    }

    /**
     * Creates the expected irb submission date email subject.
     *
     * @param request
     *            the request
     * @return the string
     */
    public static String createExpectedIRBSubmissionDateEmailSubject(final Request request) {
        StringBuffer subject = createDARTDefaultSubject(request, new StringBuffer());

        subject.append("Expected IRB Submission Date Expiring Today");

        return subject.toString();
    }

    /**
     * Creates the expected IRB submission date email body.
     *
     * @param request
     *            the request
     * @return the string
     */
    public static String createExpectedIRBSubmissionDateEmailBody(final Request request) {

        StringBuffer body = new StringBuffer();

        body.append("DART: Your data access for Preparatory to Research expires today. "
                + "You may amend the request if you need more time as long as you have not "
                + "already submitted your protocol to your IRB. Please review your request " + "below if you have questions.");

        appendPreparatoryRequestAttributes(request, body);

        appendDartIndexPageInstructions(body);

        return body.toString();
    }
    
    public static void createAndSendModifyReviewGroupsEmails(Request request, List<Group> groupList, Date changeDate, String topic, String message){
        
        String subject = createModifyReviewGroupsEmailSubject(request, topic);
        String body = createModifyReviewGroupsEmailBody(request, changeDate, message);
        emailRequestorAndAllNotifications(request, subject, body);
        sendEmailToGroupAndGroupMailBox(groupList, subject, body);
        
    }
    
    public static String createModifyReviewGroupsEmailSubject(final Request request, String topic) {
        StringBuffer subject = createDARTDefaultSubject(request, new StringBuffer());

        subject.append(topic);

        return subject.toString();
    }
    
    public static String createModifyReviewGroupsEmailBody(final Request request, Date date, String message) {

        StringBuffer body = new StringBuffer();

        body.append("DART: The additional reviews for this request have changed. See message below for details.");        
        body.append("\r\rMessage: " + message);

        appendStudyName(request, body);
        appendPrincipalInvestigator(request, body);
        
        body.append("\r\rDate Reviews Changed: " + date.toString());
                  
        appendDartTrackingNumber(request, body);

        appendDartIndexPageInstructions(body);

        return body.toString();
    }
    
    public static void createAndSendChangeRequestedEmails(Request request, Group group, Date changeDate, String topic, String message){
        
        String subject = createChangeRequestedEmailSubject(request, group, topic);
        String body = createChangeRequestedEmailBody(request, group, changeDate, message);
        emailRequestorAndAllNotifications(request, subject, body);
        
    }
    
    public static String createChangeRequestedEmailSubject(Request request, Group group, String inputTopic){
        
        StringBuffer subject = createDARTDefaultSubject(request, new StringBuffer());
        subject.append("Change Requested by " + group.getShortName());
        subject.append(" - " + inputTopic);
        
        return subject.toString();
        
    }
    
    public static String createChangeRequestedEmailBody(Request request, Group group, Date changeRequestDate, String inputMessage){
        StringBuffer body = new StringBuffer();

        appendDartTrackingNumber(request, body);
        appendStudyName(request, body);
        appendPrincipalInvestigator(request, body);

        body.append("\r\rDate Change Requested: " + changeRequestDate.toString());
        body.append("\r\r Following its review, " + group.getShortName() + 
                " has requested a change or additional information for this DART request. "
                + "Please review the message below and use DART to take the action requested. "
                + "If you have questions you may respond to the reviewer through the DART "
                + "Communications function. The current status of this request is “Change Request.” "
                + "Once you have taken the action requested be sure to resubmit the request through DART "
                + "so the request status will be updated.");

        body.append("\r\rMessage: " + inputMessage);    

        appendDartIndexPageInstructions(body);

        return body.toString();

    }
    
    public static void createAndSendChangeSubmittedEmails(Request request, Group group, Date changeDate){
        
        String subject = createChangeSubmittedEmailSubject(request, group);
        String body = createChangeSubmittedEmailBody(request, group, changeDate);
        
        sendEmailToGroupAndGroupMailBox(group, subject, body);
        
    }
    
    public static String createChangeSubmittedEmailSubject(Request request, Group group){
        
        StringBuffer subject = createDARTDefaultSubject(request, new StringBuffer());
        subject.append("Change Requested by " + group.getShortName());
        subject.append(" - " + "Submitted");
        
        return subject.toString();
        
    }
    
    public static String createChangeSubmittedEmailBody(Request request, Group group, Date changeSubmitDate){
        StringBuffer body = new StringBuffer();

        appendDartTrackingNumber(request, body);
        appendStudyName(request, body);
        appendPrincipalInvestigator(request, body);

        body.append("\r\rDate Change Submitted: " + changeSubmitDate.toString());
        
        body.append("\r\r Reminder:  Please click on the Communications icon located in the top right "
                + "hand corner to view any communications that may have been sent for your review or action.");

        appendDartIndexPageInstructions(body);

        return body.toString();

    }

    /**
     * Creates the group member email subject.
     *
     * @param workflow
     *            the workflow
     * @param request
     *            the request
     * @param fullName
     *            the full name
     * @param groupShortName
     *            the group short name
     * @param action
     *            the action
     * @return the string buffer
     */
    public static StringBuffer createGroupMemberEmailSubject(final RequestWorkflow workflow, final Request request,
            final String groupShortName, final int action) {
        StringBuffer subject = createDARTDefaultSubject(request);

        subject.append(AbstractWorkflow.getActionName(action));

        if (action == Workflow.WF_OPERATION_APPROVE || action == Workflow.WF_OPERATION_DENY
                || action == Workflow.WF_OPERATION_CHANGE_REQUEST) {
            subject.append(" by ");

            subject.append(groupShortName);
        } else {
            if (action == Workflow.WF_OPERATION_SUBMIT) {

                try {
                    RequestStatus status = request.getStatus();
                    if (workflow != null) {
                        status = workflow.getRequestStatus();
                    }

                    if (status.getId() == RequestStatus.CHANGE_REQUESTED.getId()) {
                        subject.append(" With Changes");
                    }
                } catch (ObjectNotFoundException e) {
                    LOG.error("Failed to get RequestStatus: " + e.getMessage());
                }
            }
        }

        return subject;
    }

    /**
     * Creates the dart default subject.
     *
     * @param request
     *            the request
     * @param fullName
     *            the full name
     * @return the string buffer
     */
    public static StringBuffer createDARTDefaultSubject(final Request request, StringBuffer fullName) {

        StringBuffer subject = new StringBuffer();
        subject.append(request.getTrackingNumber());

        String principalInvestigatorFullName = request.getPrincipalInvestigator();
        if (!principalInvestigatorFullName.isEmpty()) {
            fullName.append(principalInvestigatorFullName);
            String lastName = getPrincipalInvestigatorsLastName(fullName.toString());
            subject.append(" - ").append(lastName);
        }

        appendRequestType(request, subject);
        return subject;
    }
    

    /**
     * Creates the dart default subject.
     *
     * @param request
     *            the request
     * @return the string buffer
     */
    public static StringBuffer createDARTDefaultSubject(final Request request) {

        StringBuffer subject = new StringBuffer();

        if (request != null) {
            subject.append(request.getTrackingNumber());
            String principalInvestigatorFullName = request.getPrincipalInvestigator();
            if (!principalInvestigatorFullName.isEmpty()) {
                String lastName = getPrincipalInvestigatorsLastName(principalInvestigatorFullName);
                subject.append(" - ").append(lastName);
            }
        }

        appendRequestType(request, subject);
        return subject;
    }

    /**
     * Sends the "Request Completed" email when all of the workflows are completed.
     * 
     * Sends the "Request Completed" email to the request participants with notifications selected.
     *
     * @param request
     *            the request
     * @param workflow
     *            the workflow
     * @param group
     *            the group
     * @param action
     *            the action
     */
    public static void createAndSendRequestCompletedEmail(final Request request, final RequestWorkflow workflow,
            final Group group, final int action) {

        Group.initialize();
        Role.initialize();

        if (request != null) {

            String groupShortName = "";
            if (group != null) {
                groupShortName = group.getShortName();
            }

            String subject = createDARTDefaultSubject(request).append("Request Completed").toString();
            String body = createRequestCompletedEmailBody(request, groupShortName, action);

            EmailUtils.emailRequestorAndAllNotifications(request, subject.toString(), body.toString());

            // if this is an NDS workflow, email NDS
            if (workflow != null && workflow.getWorkflowTemplate() != null) {
                if (workflow.getWorkflowTemplate().getWorkflowTypeId() == WorkflowResolver.WF_NDS) { // NDS workflow?
                    sendEmailToNDSAdminList(subject.toString(), body.toString());

                    // notify Homeless Registry once the final NDS review is approved
                    if (action == Workflow.WF_OPERATION_APPROVE) {
                        sentEmailToHomelessRegistryAtFinalNDSApproval(request, workflow, subject.toString(), body.toString());
                    }
                }
            }

            if (action == Workflow.WF_OPERATION_APPROVE) {

                sendEmailToDARTAdminList(subject.toString(), body.toString());
                sendEmailToVINCIDataManagersEmail(subject.toString(), body.toString());
                sendEmailToGroupAndRole(group, Role.READ_ONLY_STAFF, subject.toString(), body.toString());
            }
        }
    }
    
    /**
     * Creates the and send operational approval emails.
     *
     * @param workflow the workflow
     * @param request the request
     */
    public static void createAndSendOperationalApprovalEmails(final RequestWorkflow workflow, final Request request) {
        final String groupShortName = Group.NDS.getShortName();
        StringBuffer subject = EmailUtils.createGroupMemberEmailSubject(workflow, request, groupShortName,
                Workflow.WF_OPERATION_APPROVE);

        StringBuffer emailBody = new StringBuffer(request.getRequestTypeString() + " Request ");
        emailBody.append(request.getTrackingNumber());
        emailBody.append(" has been reviewed and approved for the project ");
        emailBody.append(request.getActivity().getOfficialName());
        emailBody.append(" for which you are identified as participant.");

        EmailUtils.appendDartIndexPageInstructions(emailBody);

        // email requester
        EmailUtils.emailRequestorAndAllNotifications(request, subject.toString(), emailBody.toString());

        // generate the body
        StringBuffer closedBody = new StringBuffer("A Data Access Request has been reviewed and approved:");
        closedBody.append("\r\rStudy Name: ").append(request.getActivity().getOfficialName());
        closedBody.append("\rIRB Number: ").append(request.getIrbNumber());
        closedBody.append("\rTracking Number: ").append(request.getTrackingNumber());

        EmailUtils.appendDartIndexPageInstructions(closedBody);

        EmailUtils.sendEmailToDARTAdminList(subject.toString(), closedBody.toString());

        // send an email to a data distribution list notifying certain people that the request is ready to get data
        EmailUtils.sendEmailToVINCIDataManagersEmail(subject.toString(), closedBody.toString());

        // notify Homeless Registry once the final NDS review is approved
        EmailUtils.sentEmailToHomelessRegistryAtFinalNDSApproval(request, workflow, subject.toString(),
                closedBody.toString());
    }
    
    public static void createAndSendRequestReadyForFinalApprovalEmail(final RequestWorkflow workflow, final Request request) {
        String groupShortName = "the Study Participants";
        StringBuffer subject = EmailUtils.createGroupMemberEmailSubject(workflow, request, groupShortName,
                Workflow.WF_OPERATION_SUBMIT);

        StringBuffer initialNDSBody =
                new StringBuffer("A new " + request.getRequestTypeString() + " Request has been submitted for final approval:");

        if (Request.DATA_ACCESS == request.getRequestTypeString()){
            EmailUtils.appendDartRequestAttributes(request, initialNDSBody);
        } else if (Request.PREPARATORY_TO_RESEARCH_ACCESS == request.getRequestTypeString()){
            EmailUtils.appendPreparatoryRequestAttributes(request, initialNDSBody);
        }

        EmailUtils.appendInitiatedBy(request, initialNDSBody);

        EmailUtils.appendDartIndexPageInstructions(initialNDSBody);
        
        EmailUtils.sendEmailToNDSAdminList(subject.toString(), initialNDSBody.toString());
    }
    
    /**
     * Send nds operational close emails.
     *
     * @param workflow
     *            the workflow
     * @param request
     *            the request
     */
    public static void createAndSendNDSOperationalCloseEmails(final RequestWorkflow workflow, final Request request) {
        String tempShortName = "the Study Participants";
        StringBuffer subject =
                EmailUtils.createGroupMemberEmailSubject(workflow, request, tempShortName, Workflow.WF_OPERATION_CLOSE);

        StringBuffer closedBody = new StringBuffer("The following Data Access Request has been closed:");
        if (DartRequest.class.isAssignableFrom(request.getClass())) {
            EmailUtils.appendDartRequestAttributes(request, closedBody);
        } else if (PreparatoryRequest.class.isAssignableFrom(request.getClass())) {
            EmailUtils.appendPreparatoryRequestAttributes(request, closedBody);
        }
        EmailUtils.appendDartIndexPageInstructions(closedBody);

        EmailUtils.emailRequestorAndAllNotifications(request, subject.toString(), closedBody.toString());
    }




    /**
     * Send an email to the requestor and all participants that have requested notification.
     *
     * @param subject
     *            the subject
     * @param text
     *            the text
     */
    public static void emailRequestorAndAllNotifications(final Request request, final String subject, final String body) {

        sendEmailToParticipants(request.getParticipants(), subject, body);

      //If the creator was not a participant with notifications turned on then send them an email.
        if (!isCreatorAParticipantWithNotifications(request)) {
            sendEmailToUserLoginId(request.getCreatedBy(), subject, body);
        }
    }

    /**
     * Checks if a creator is a participant with notifications.
     * 
     *
     * @param request
     *            the request
     * @return true, if is creator is a participant with notifications
     */
    private static boolean isCreatorAParticipantWithNotifications(final Request request) {
        if (request != null && request.getCreatedBy() != null) {
            for (Participant participant : request.getParticipants()) {
                if (participant.getNotification()) {
                    if (participant != null && participant.getPerson() != null && participant.getPerson().getName() != null) {
                        if (request.getCreatedBy().toUpperCase(Locale.ENGLISH).equals(participant.getPerson().getName().toUpperCase(Locale.ENGLISH))) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    /**
     * Creates the body of the "Request Completed" email to be sent to the request participants when all of the workflows are
     * completed.
     *
     * @param request
     *            the request
     * @param groupShortName
     *            the group short name
     * @param action
     *            the action
     * @return the string
     */
    private static String createRequestCompletedEmailBody(final Request request, final String groupShortName,
            final int action) {

        StringBuffer body = new StringBuffer();

        body.append(groupShortName + " has ");

        if (action == Workflow.WF_OPERATION_APPROVE) {
            body.append("approved");
        } else if (action == Workflow.WF_OPERATION_DENY) {
            body.append("denied");
           
        }

        body.append(
                " this request. All reviews associated with this request have now been completed. This request may now be amended as needed. Please review this request below if you have questions.\r");

        if (DartRequest.class.isAssignableFrom(request.getClass()))
        {
            appendStudyName(request, body);
            appendIRBNumber(request, body);
            appendDartTrackingNumber(request, body);
        } else if (PreparatoryRequest.class.isAssignableFrom(request.getClass()))
        {
            appendPreparatoryRequestAttributes(request, body);
        }
        
        appendDartIndexPageInstructions(body);

        return body.toString();
    }

    /**
     * Sends the "Review Pending" email.
     * 
     * Sends the "Review Pending" email to the request participants with notifications selected.
     *
     * @param request
     *            the request
     * @param workflow
     *            the workflow
     * @param group
     *            the group
     * @param action
     *            the action
     */
    public static void createAndSendReviewPendingEmail(final Request request, final RequestWorkflow workflow, final Group group,
            final int action) {

        Group.initialize();
        Role.initialize();

        if (request != null) {

            StringBuffer subject = new StringBuffer();

            String groupShortName = "";
            if (group != null) {
                groupShortName = group.getShortName();
            } // end if

            subject = createGroupMemberEmailSubject(null, request, groupShortName, action);
            subject.append("; Other reviews pending");

            StringBuffer body = createReviewPendingEmailBody(request, groupShortName, action);

            EmailUtils.emailRequestorAndAllNotifications(request, subject.toString(), body.toString());

            // if this is an NDS workflow, email NDS
            if (workflow != null && workflow.getWorkflowTemplate() != null) {
                if (workflow.getWorkflowTemplate().getWorkflowTypeId() == WorkflowResolver.WF_NDS) {
                    sendEmailToNDSAdminList(subject.toString(), body.toString());

                    // notify Homeless Registry once the final NDS review is approved
                    if (action == Workflow.WF_OPERATION_APPROVE) {
                        sentEmailToHomelessRegistryAtFinalNDSApproval(request, workflow, subject.toString(), body.toString());
                    }
                }
            }

            if (action == Workflow.WF_OPERATION_APPROVE) { // only email the groups if the request is approved?

                sendEmailToDARTAdminList(subject.toString(), body.toString());
                sendEmailToVINCIDataManagersEmail(subject.toString(), body.toString());
                sendEmailToGroupAndRole(group, Role.READ_ONLY_STAFF, subject.toString(), body.toString());
            }
        }
    }

    /**
     * Creates the body of the "Review Pending" email to be sent to the request participants when a review is completed but
     * there are other approvals pending.
     * 
     *
     * @param request
     *            the request
     * @param groupShortName
     *            the group short name
     * @param action
     *            the action
     * @return the string buffer
     */
    private static StringBuffer createReviewPendingEmailBody(final Request request, final String groupShortName,
            final int action) {

        StringBuffer body = new StringBuffer();

        body.append("This DART Request has been reviewed and ");

        if (action == Workflow.WF_OPERATION_APPROVE) {
            body.append("approved");
        } else if (action == Workflow.WF_OPERATION_DENY) {
            body.append("denied");
        }

        body.append(" by " + groupShortName);
        body.append(
                ". Additional reviews by other data stewards are pending. This request may not be amended until all reviews are completed. Please review this request below if you have questions.\r");

        if (DartRequest.class.isAssignableFrom(request.getClass())){
            appendStudyName(request, body);
            appendIRBNumber(request, body);
            appendDartTrackingNumber(request, body);
        } else if (PreparatoryRequest.class.isAssignableFrom(request.getClass()))
        {
            appendPreparatoryRequestAttributes(request, body);
        }


        appendDartIndexPageInstructions(body);

        return body;
    }

    /**
     * Creates the initial review email body.
     *
     * @param request
     *            the request
     * @return the string buffer
     */
    public static StringBuffer createInitialReviewEmailBody(final Request request) {

        StringBuffer body = new StringBuffer("A new " + request.getRequestTypeString() + " Request has been submitted for your approval:");

        if (request != null) {
            if (DartRequest.class.isAssignableFrom(request.getClass())){
                appendDartRequestAttributes(request, body);
            } else if (PreparatoryRequest.class.isAssignableFrom(request.getClass())){
                appendPreparatoryRequestAttributes(request, body);
            }
                
            appendDartIndexPageInstructions(body);

        }

        return body;
    }

    /**
     * Sent email to homeless registry at final nds approval.
     *
     * @param request
     *            the request
     * @param workflow
     *            the workflow
     * @param subject
     *            the subject
     * @param body
     *            the body
     */
    public static void sentEmailToHomelessRegistryAtFinalNDSApproval(final Request request, final RequestWorkflow workflow,
            final String subject, final String body) {

        // notify Homeless Registry once the final NDS review is approved
        DataSource homelessRegistryDS = null;
        try {
            homelessRegistryDS = DataSource.findById(1036);
        } catch (Exception exc) {
            // log.error("Error retrieving data source");
        }

        boolean hasHomeless = false;
        if (homelessRegistryDS != null && request.getDataSources().contains(homelessRegistryDS)) {
            hasHomeless = true; // requested the Homeless Registry data source
        }

        Review homelessReview = request.findReviewAssignedToGroup(workflow, Group.HOMELESS_REGISTRY);

        if (homelessReview != null || hasHomeless == true) {
            sendEmailToGroupAndGroupMailBox(Group.HOMELESS_REGISTRY, subject, body);
        }
    }

    /**
     * Creates and sends the "Request Initiated" email to the request creator.
     *
     * @param request
     *            the request
     * @param userLoginId
     *            the user login id
     */
    public static void createAndSendRequestInitiatedEmail(final Request request, final String userLoginId) {

        Group.initialize(); // initialize the groups and roles, just in case
        Role.initialize();

        if (request != null) {

            StringBuffer subject = new StringBuffer();

            subject = createRequestInitiatedEmailSubject(request);

            StringBuffer body = createRequestInitiatedEmailBody(request);
            StringBuffer plainTextBody = createRequestInitiatedEmailBodyPlainText(request);

            MailManager mailManager = DartObjectFactory.getInstance().getMailManager();

            final String attachmentFilename = "DART Considerations.pdf";

            if (request.isAmendment() == true) {

                emailRequestorAndAllNotificationsPlainAndHTMLWithAttachment(request, subject.toString(),
                        plainTextBody.toString(), body.toString(), false, attachmentFilename);

            } else {

                mailManager.sendPlainAndHTMLMailWithAttachment(userLoginId, subject.toString(), plainTextBody.toString(),
                        body.toString(), false, attachmentFilename);

            }

            sendEmailToVINCIDataManagersEmail(subject.toString(), body.toString());

        }
    }

    /**
     * Send an email to the requestor and all participants that have requested notification.
     *
     * @param subject
     *            the subject
     * @param plainBody
     *            the plain body
     * @param htmlBody
     *            the html body
     * @param bIncludePrefix
     *            the b include prefix
     * @param attachmentFilename
     *            the attachment filename
     */
    public static void emailRequestorAndAllNotificationsPlainAndHTMLWithAttachment(final Request request, final String subject,
            final String plainBody, final String htmlBody, final boolean bIncludePrefix, final String attachmentFilename) {

        MailManager mailManager = DartObjectFactory.getInstance().getMailManager();

        // send an email to the request owner.
        if (mailManager != null) {

            for (Participant participant : request.getParticipants()) {
                if (participant.getNotification()) {

                    mailManager.sendPlainAndHTMLMailWithAttachment(participant.getPerson().getName().toUpperCase(), subject,
                            plainBody, htmlBody, bIncludePrefix, attachmentFilename);

                }
            }

            //If the creator was not a participant with notifications turned on then send them an email.
            if (!isCreatorAParticipantWithNotifications(request)) {
                mailManager.sendPlainAndHTMLMailWithAttachment(request.getCreatedBy(), subject, plainBody, htmlBody,
                        bIncludePrefix, attachmentFilename);
            }
        }
    }

    /**
     * Creates the subject for the "Request Initiated" email.
     *
     * @param request
     *            the request
     * @return the string buffer
     */
    private static StringBuffer createRequestInitiatedEmailSubject(final Request request) {

        StringBuffer subject = new StringBuffer();

        if (request != null) {
            subject.append("DART ");

            subject.append(request.getTrackingNumber());

            subject.append(" has been Initiated - Please Read Before Submitting This Request - Do Not Reply");
        } // end if

        return subject;
    }

    /**
     * Creates the body of the "Request Initiated" email.
     * 
     * Greetings DART User, You are receiving this email because you initiated a new Data Access Request Tracker (DART) request
     * and it is important that you read this email in order for you to understand the process. Please note that DART is for IRB
     * Research data requests only and not Operations or Preparatory to Research requests. This email provides links to helpful
     * resources, considerations to take into account when requesting data access, and what to expect. If you have questions,
     * please contact      @domain or NDS.                      @domain. Do not reply to this email as it is system generated.
     * 
     * About Your DART Request DART Tracking Number: [Tracking_Number] Study/Protocol Name: [Study_Long_Name]
     * 
     * DART Considerations • Please read the DART User Guide as it contains valuable information that will save you time and
     * effort. • One protocol per DART request. Changes after approval must be done with an amendment to the original request. •
     * Your official VA Email address is used by DART for communication of notices so please check it frequently. • If you
     * intend to use VINCI Workspace for data storage and analysis - As part of your IRB, you will want to state that you are
     * using VINCI for data storage and analysis. See VINCI Description for IRBs and VINCI Information Security Description. •
     * If you are requesting CDW data, you can request to have a VINCI Concierge work with you on a “Data Needs Assessment” to
     * determine exactly what data you need to request so you get the right data the first time. Just send as much data detail
     * as possible to      @domain to initiate the request. See these pages for information on data first: o VHA Data Portal:
     * http://DNS.DNS       /DataSources/DataSourcesOverview.aspx o VINCI/CDW Data Descriptions:
     * http://DNS.DNS       /vincicentral/Data.html • Real SSN access requires an additional form signed by your IRB. See
     * this page for more information: http://DNS.DNS   /Access/Real-SSN-Request-Process.htm. • For information
     * on how to fill out a Research Request Memo, see Appendix A of the DART User Guide. • If you are requesting mainframe
     * access, you will need to submit a 9957 to your local CUPS POC prior to completing your Research Request Memo. See
     * Appendix B in the DART User Guide on how to fill-out the 9957. NOTE: The 9957 is still required for creating a Mainframe
     * account with your Local CUPS POC. NDS no longer requires or utilizes the 9957 for data access requests for the data
     * sources NDS manages. • Please note that you cannot remove any data from the VINCI Workspace that contains PHI/PII per VHA
     * Privacy and Security regulations without first obtaining permission through a DART amendment to the data steward who
     * provided the data access. Violation can result in severe penalties so if in doubt, contact      @domain for guidance and
     * policies before downloading. • If you have more than one version of a required document, you will need to combine the
     * documents into one. For example, you will need to combine an original IRB and any continuing IRBs into one document that
     * is then uploaded for the IRB document. • For CAPRI access, many times studies only need one person to access CAPRI,
     * however, the DART application will ask for an EHR document for everybody checked for data access. For users that WILL NOT
     * require CAPRI access, upload a Word document in place of the EHR form that states “this user does not need CAPRI access.”
     * • If you need to change your study name or amendment narrative after they have been created, send an email with the
     * correction to      @domain as you are not able to change them yourself in DART. • Please note that after approval of
     * CDW/VINCI data requests, a technical evaluation may be required by VINCI staff to determine if the data request is
     * technically feasible. This may require modification to the request. This is often due to studies requesting all data
     * available so please limit your request to only the minimal amount of data necessary to achieve your objectives.
     * 
     * DART Expectations • Once your request is submitted, it is sent for review by the appropriate Approvers. Allow 2-8 weeks
     * for processing depending on complexity and completeness of the request. • If a Reviewer has questions or is requesting
     * changes, they will contact you through the DART Communications functionality which will email a notice to your VA email
     * address when a new message has been posted. Respond in DART using the Communications functionality or submitting
     * requested changes. Do not reply to the email notice as it will not be read. Failure to respond within 90 days will result
     * in denial of the request. • DART will send notices to you for each step in the review process so you know where it
     * stands. • If you requested CDW data, VINCI will be automatically notified once Final NDS Approval is received. A VINCI
     * Data Manager will contact you within a week to work with you one-on-one to make the approved data available as soon as
     * possible. • If you requested Mainframe data, CDW Operations will contact you to establish access. • If you requested
     * “Other” data, the appropriate data steward will contact you to establish access. • VINCI is automatically notified of
     * requests to store the data in the VINCI environment. VINCI will set up your staff for access and notify your team within
     * one business week.
     * 
     * Resources and Links • DART Application: https://DNS             .DNS       :PORT/vinci_dart_client/dart9/index.html •
     * DART Overview and Forms: http://DNS.DNS       /DataAccess/DARTRequestProcess.aspx • DART User Guide –
     * http://DNS.DNS       /vincicentral/documents/DART_User_Guide.pdf • Presentation on how to use DART -
     * http://www.hsrd.research.DNS   /for_researchers/cyber_seminars/archives/video_archive.cfm?SessionID=906 • VHA Data
     * Portal: http://DNS.DNS       /Home.aspx • VINCI Central:
     * http://DNS.DNS       /vincicentral/default.aspx
     * 
     * Please take time to read the DART User Guide.
     * 
     * Sincerely, The DART Team
     * 
     * 
     * 
     * Embedded link URLs are as follows:
     * 
     * DART User Guide URL is http://DNS.DNS       /vincicentral/documents/DART_User_Guide.pdf
     * 
     * VINCI Description for IRBs URL is http://DNS.DNS       /vincicentral/documents/VINCI_Description_for_IRBs.docx
     * 
     * VINCI Information Security Description URL is
     * http://DNS.DNS       /vincicentral/documents/VINCI_Information_Security_Description.pdf
     *
     * @param request
     *            the request
     * @return the string buffer
     */
    private static StringBuffer createRequestInitiatedEmailBody(final Request request) {

        StringBuffer body = new StringBuffer();

        // &bull; //U+2002, bullet point
        // &#9702; //U+25E6, white bullet
        // long dash: &#8211;

        if (request != null) {

            body.append(
                    "<html xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:w=\"urn:schemas-microsoft-com:office:word\" xmlns:m=\"http://schemas.microsoft.com/office/2004/12/omml\" xmlns=\"http://www.w3.org/TR/REC-html40\"><head><META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=us-ascii\"><meta name=Generator content=\"Microsoft Word 14 (filtered medium)\">");
            body.append("<style><!-- " + "/* Font Definitions */ " + "@font-face " + "	{font-family:Wingdings; "
                    + "	panose-1:5 0 0 0 0 0 0 0 0 0;} " + "@font-face " + "	{font-family:Wingdings; "
                    + "	panose-1:5 0 0 0 0 0 0 0 0 0;} " + "@font-face " + "	{font-family:Calibri; "
                    + "	panose-1:2 15 5 2 2 2 4 3 2 4;} " + "/* Style Definitions */ "
                    + "p.MsoNormal, li.MsoNormal, div.MsoNormal " + "	{margin:0in; " + "	margin-bottom:.0001pt; "
                    + "	font-size:11.0pt; " + "	font-family:\"Times New Roman\",\"serif\";} " + "a:link, span.MsoHyperlink "
                    + "	{mso-style-priority:99; " + "	color:blue; " + "	text-decoration:underline;} "
                    + "a:visited, span.MsoHyperlinkFollowed " + "	{mso-style-priority:99; " + "	color:purple; "
                    + "	text-decoration:underline;} " + "p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph "
                    + "	{mso-style-priority:34; " + "	margin:0in; " + "	margin-bottom:.0001pt; " + "	font-size:11.0pt; "
                    + "	font-family:\"Times New Roman\",\"serif\";} " + "span.EmailStyle17 "
                    + "	{mso-style-type:personal-compose; " + "	font-family:\"Calibri\",\"sans-serif\"; "
                    + "	color:windowtext;} " + ".MsoChpDefault " + "	{mso-style-type:export-only; "
                    + "	font-family:\"Calibri\",\"sans-serif\";} " + "@page WordSection1 " + "	{size:8.5in 11.0in; "
                    + "	margin:1.0in 1.0in 1.0in 1.0in;} " + "div.WordSection1 " + "	{page:WordSection1;} "
                    + "/* List Definitions */ " + "@list l0 " + "	{mso-list-id:2034455717; " + "	mso-list-type:hybrid; "
                    + "	mso-list-template-ids:341211824 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} "
                    + "@list l0:level1 " + "	{mso-level-number-format:bullet; " + "	mso-level-text:\\" + "F0B7; "
                    + "	mso-level-tab-stop:none; " + "	mso-level-number-position:left; " + "	text-indent:-.25in; "
                    + "	font-family:Symbol;} " + "@list l0:level2 " + "	{mso-level-number-format:bullet; "
                    + "	mso-level-text:o; " + "	mso-level-tab-stop:none; " + "	mso-level-number-position:left; "
                    + "	text-indent:-.25in; " + "	font-family:\"Courier New\";} " + "@list l0:level3 "
                    + "	{mso-level-number-format:bullet; " + "	mso-level-text:\\" + "F0A7; " + "	mso-level-tab-stop:none; "
                    + "	mso-level-number-position:left; " + "	text-indent:-.25in; " + "	font-family:Wingdings;} "
                    + "@list l0:level4 " + "	{mso-level-number-format:bullet; " + "	mso-level-text:\\" + "F0B7; "
                    + "	mso-level-tab-stop:none; " + "	mso-level-number-position:left; " + "	text-indent:-.25in; "
                    + "	font-family:Symbol;} " + "@list l0:level5 " + "	{mso-level-number-format:bullet; "
                    + "	mso-level-text:o; " + "	mso-level-tab-stop:none; " + "	mso-level-number-position:left; "
                    + "	text-indent:-.25in; " + "	font-family:\"Courier New\";} " + "@list l0:level6 "
                    + "	{mso-level-number-format:bullet; " + "	mso-level-text:\\" + "F0A7; " + "	mso-level-tab-stop:none; "
                    + "	mso-level-number-position:left; " + "	text-indent:-.25in; " + "	font-family:Wingdings;} "
                    + "@list l0:level7 " + "	{mso-level-number-format:bullet; " + "	mso-level-text:\\" + "F0B7; "
                    + "	mso-level-tab-stop:none; " + "	mso-level-number-position:left; " + "	text-indent:-.25in; "
                    + "	font-family:Symbol;} " + "@list l0:level8 " + "	{mso-level-number-format:bullet; "
                    + "	mso-level-text:o; " + "	mso-level-tab-stop:none; " + "	mso-level-number-position:left; "
                    + "	text-indent:-.25in; " + "	font-family:\"Courier New\";} " + "@list l0:level9 "
                    + "	{mso-level-number-format:bullet; " + "	mso-level-text:\\" + "F0A7; " + "	mso-level-tab-stop:none; "
                    + "	mso-level-number-position:left; " + "	text-indent:-.25in; " + "	font-family:Wingdings;} " + "ol "
                    + "	{margin-bottom:0in;} " + "ul " + "	{margin-bottom:0in;} " + "--></style>");
            body.append("<!--[if gte mso 9]><xml><o:shapedefaults v:ext=\"edit\" spidmax=\"1026\" /></xml><![endif]-->");
            body.append(
                    "<!--[if gte mso 9]><xml><o:shapelayout v:ext=\"edit\"><o:idmap v:ext=\"edit\" data=\"1\" /></o:shapelayout></xml><![endif]-->");
            body.append("</head>");

            body.append("<body lang=EN-US link=blue vlink=purple><div class=WordSection1>");
            body.append(
                    "<p class=MsoNormal><b><span style='font-family:\"Calibri\",\"sans-serif\"'>Greetings DART User,<o:p></o:p></span></b></p>");

            if (request.isAmendment() == true) {

                body.append(
                        "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'>You are receiving this email because you amended a "+ request.getRequestTypeString() + " Request Tracker (DART) request:<o:p></o:p></span></p>");

                body.append("<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'> <o:p></o:p></span></p>");
                body.append(
                        "<p class=MsoListParagraph style='margin-left:.5in;text-indent:-.25in;mso-list:l0 level1 lfo1'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>&middot;<span style='font:7.0pt \"Times New Roman\"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]>");
                body.append("<span style='font-family:\"Calibri\",\"sans-serif\"'>DART Tracking Number: "
                        + request.getTrackingNumber() + "<o:p></o:p></span></p>");

                body.append(
                        "<p class=MsoListParagraph style='margin-left:.5in;text-indent:-.25in;mso-list:l0 level1 lfo1'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>&middot;<span style='font:7.0pt \"Times New Roman\"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]>");
                body.append("<span style='font-family:\"Calibri\",\"sans-serif\"'>Study/Protocol Name: "
                        + request.getActivity().getOfficialName() + "<o:p></o:p></span></p>");

                body.append(
                        "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'><o:p>&nbsp;</o:p></span></p>");
                body.append(
                        "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'>It is important that you read the attached PDF document in order for you to understand the process if you do not already as some things may have changed since your last request.<o:p></o:p></span></p>");

            } else {

                body.append(
                        "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'>You are receiving this email because you initiated a new " + request.getRequestTypeString() + " Request Tracker (DART) request:<o:p></o:p></span></p>");

                body.append(
                        "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'> <o:p></o:p></span></p><p class=MsoListParagraph style='margin-left:.5in;text-indent:-.25in;mso-list:l0 level1 lfo1'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>&middot;<span style='font:7.0pt \"Times New Roman\"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]>");
                body.append("<span style='font-family:\"Calibri\",\"sans-serif\"'>DART Tracking Number: "
                        + request.getTrackingNumber() + "<o:p></o:p></span></p>");

                body.append(
                        "<p class=MsoListParagraph style='margin-left:.5in;text-indent:-.25in;mso-list:l0 level1 lfo1'><![if !supportLists]><span style='font-family:Symbol'><span style='mso-list:Ignore'>&middot;<span style='font:7.0pt \"Times New Roman\"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]>");
                body.append("<span style='font-family:\"Calibri\",\"sans-serif\"'>Study/Protocol Name: "
                        + request.getActivity().getOfficialName() + "<o:p></o:p></span></p>");

                body.append(
                        "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'><o:p>&nbsp;</o:p></span></p>");
                body.append(
                        "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'>It is important that you read the attached PDF document in order for you to understand the process.  Please note that only IRB approved research and Preparatory to Research requests should be submitted through DART.  Operational access is requested through other processes.<o:p></o:p></span></p>");

            } // end else

            body.append("<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'><o:p>&nbsp;</o:p></span></p>");
            body.append(
                    "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'>The attached document provides links to helpful resources, considerations to take into account when requesting data access, and what to expect.  The </span><a href=\"http://DNS.DNS       /vincicentral/documents/DART_User_Guide.pdf\"><span style='font-family:\"Calibri\",\"sans-serif\"'>DART User Guide</span></a><span style='font-family:\"Calibri\",\"sans-serif\"'> provides complete details about how to use DART.");
            body.append(
                    "  If you need assistance with completing the DART request or have questions, please contact the VINCI Concierge Service at </span><a href=\"mailto:     @domain\"><span style='font-family:\"Calibri\",\"sans-serif\"'>     @domain</span></a><span style='font-family:\"Calibri\",\"sans-serif\"'> or </span><a href=\"mailto:NDS.                      @domain\"><span style='font-family:\"Calibri\",\"sans-serif\"'>NDS.                      @domain</span></a><span style='font-family:\"Calibri\",\"sans-serif\"'>.  Do not reply to this email as it is system generated.<o:p></o:p></span></p>");
            body.append("<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'><o:p>&nbsp;</o:p></span></p>");
            body.append(
                    "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'>Remember, please take time to read the </span><a href=\"http://DNS.DNS       /VinciCentral/2016/documents/DART_User_Guide.pdf\"><span style='font-family:\"Calibri\",\"sans-serif\"'>DART User Guide</span></a><span style='font-family:\"Calibri\",\"sans-serif\"'>.<o:p></o:p></span></p>");
            body.append("<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'><o:p>&nbsp;</o:p></span></p>");

            body.append(
                    "<p class=MsoNormal><span style='font-family:\"Calibri\",\"sans-serif\"'>Sincerely,<o:p></o:p></span></p>");
            body.append(
                    "<p class=MsoNormal><b><i><span style='font-family:\"Calibri\",\"sans-serif\"'>The DART Team</span></i></b><span style='font-family:\"Calibri\",\"sans-serif\"'><o:p></o:p></span></p></div></body></html>");

        }

        return body;
    }

    /**
     * Creates the request initiated email body plain text.
     *
     * @param request
     *            the request
     * @return the string buffer
     */
    private static StringBuffer createRequestInitiatedEmailBodyPlainText(final Request request) {

        StringBuffer body = new StringBuffer();

        if (request != null) {

            body.append("Greetings DART User,\r\r");

            if (request.isAmendment() == true) {

                body.append("You are receiving this email because you amended a "+ request.getRequestTypeString() + " Request Tracker (DART) request:");

                appendDartTrackingNumber(request, body);
                appendStudySlashProtocolName(request, body);

                body.append(
                        "\r\rIt is important that you read the attached PDF document in order for you to understand the process if you do not already as some things may have changed since your last request.");

            } else {

                body.append(
                        "You are receiving this email because you initiated a new Data Access Request Tracker (DART) request:");

                appendDartTrackingNumber(request, body);
                appendStudySlashProtocolName(request, body);

                body.append(
                        "\r\rIt is important that you read the attached PDF document in order for you to understand the process.  Please note that only IRB approved research and Preparatory to Research requests should be submitted through DART.  Operational access is requested through other processes.");

            } // end else

            body.append(
                    "\r\rThe attached document provides links to helpful resources, considerations to take into account when requesting data access, and what to expect.");
            body.append(
                    "  The DART User Guide provides complete details about how to use DART: http://DNS.DNS       /VinciCentral/2016/documents/DART_User_Guide.pdf.");

            body.append(
                    "\r\rIf you need assistance with completing the DART request or have questions, please contact the VINCI Concierge Service at      @domain or NDS.                      @domain.  Do not reply to this email as it is system generated.");

            body.append(
                    "\r\rRemember, please take time to read the DART User Guide: http://DNS.DNS       /vincicentral/documents/DART_User_Guide.pdf");

            body.append("\r\rSincerely,");
            body.append("\rThe DART Team");

        }

        return body;
    }

}
