/*
 * NIST HL7 Web Service
 * ProfileValidation.java Apr 11, 2008
 *
 * This code was produced by the National Institute of Standards and
 * Technology (NIST). See the "nist.disclaimer" file given in the distribution
 * for information on the use and redistribution of this software.
 */

package gov.nist.hl7.ws.profilevalidation;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import gov.nist.hl7.core.profile.Profile;
import gov.nist.hl7.core.validation.profile.ProfileValidationContext;
import gov.nist.hl7.core.validation.profile.ProfileValidationResult;
import gov.nist.hl7.ws.Logger;

public class ProfileValidation implements ProfileValidationInterface {

    protected Profile profile;
    protected String report;
    protected ProfileValidationContext profileValidContext = null;
    protected String exception = "";

    public String getLastExceptionMessage() {
        String lastException = exception;
        Logger.info("ProfileValidationInterface - User got the last exception message");
        exception = "";
        return lastException;
    }

    public String getProfileValidationReport() {
        if (report == null) {
            report = "Error: Launch the validation before";
        }
        Logger.info("ProfileValidationInterface - User got the report");
        return report;
    }

    public boolean setProfile(String xmlProfile, String profileId) throws Exception {
        try {
            // Log the file
            if (profileId == null) {
                profileId = "noid";
            }

            if (xmlProfile.length() > 2 * 1024 * 1024) {
                throw new IOException("File is too large (Max Size= 2MB)");
            }

            Logger.info("ProfileValidationInterface - User set a profile: " + profileId);
            profile = new Profile(profileId, xmlProfile);

            SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssZ");
            profile.getDocument().save(new File("../logs/HL7WS_logs/profValid_" + profileId + "_" + sdf.format(new Date()) + ".xml"));
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }
        return true;
    }

    public boolean setProfileValidationContext(
            String xmlProfileValidationContext) throws Exception {
        profileValidContext = new ProfileValidationContext();
        try {
            Logger.info("ProfileValidationInterface - User set a ProfileValidationContext");
            profileValidContext.load(xmlProfileValidationContext);
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            e.printStackTrace();
        }
        return true;
    }

    public boolean validate() throws Exception {
        boolean ret = false;

        try {
            if (profile != null) {
                Logger.info("ProfileValidationInterface - User ran a Validation");
                // create a ProfileValidationInterface object
                ProfileValidationResult pvr;
                if (profileValidContext == null) {
                    pvr = gov.nist.hl7.core.validation.profile.
                    ProfileValidation.validate(profile);
                } else {
                    pvr = gov.nist.hl7.core.validation.profile.
                    ProfileValidation.validate(profile, profileValidContext);
                }

                ret = pvr.isValid();

                // Get report
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                pvr.getReport().save(baos);
                byte [] b  = baos.toByteArray();
                report = new String(b);

                // Garbage collector
                profile = null;
                profileValidContext = null;

            } else {
                throw new IOException("Profile not initialized.");
            }
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }

        return ret;
    }

}
