/*
 * 
 */
package gov.grants.apply.support.vo;

import gov.grants.commons.CommonsGlobals;
import gov.grants.commons.util.GDGEscapeUtil;

import java.net.URLDecoder;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.log4j.Logger;

/**
 * @author wkaselow
 */
public class AttachmentDetails {
	
	private static final transient Logger log = Logger.getLogger( AttachmentDetails.class.getName() );
	
	// Submission XML elements
	public static final String ATTACHMENT_NS_URI = "http://apply.grants.gov/system/Attachments-V1.0";
	public static final String FILENAME_ELEMENT_LOCAL_PART = "FileName";
	public static final String MIME_TYPE_ELEMENT_LOCAL_PART = "MimeType";
	public static final String FILE_LOCATION_ELEMENT_LOCAL_PART = "FileLocation";
	public static final String HASH_VALUE_ELEMENT_LOCAL_PART = "HashValue";
	public static final String CID_ATTRIBUTE_LOCAL_PART = "href";
	
	public static final String HASH_VALUE_ELEMENT = "glob:HashValue";
	public static final String FILENAME_ELEMENT = "att:FileName";
	public static final String FILE_LOCATION_ELEMENT = "att:FileLocation";
	public static final String CID_ATTRIBUTE = "att:href";
	
	// Attachment meta-data
    private String contentID;
    /**
     * Uses VTD-XML toNormalizedString2(), which performs a shallow normalization
     * according to the following rules:
     * 	<br />- #xD#xA gets converted to #xA
     * 	<br />- For a character reference, append the referenced character to the normalized value.
     * 	<br />- For an entity reference, recursively apply step 3 of this algorithm to the replacement text of the entity.
     * 	<br />- For a white space character (#x20, #xD, #xA, #x9), append a space character (#x20) to the normalized value.
     * 	<br />- For another character, append the character to the normalized value. 
     * 
     * <br /><br />
     * 
     * NOTE: Does not decode URL-encoded entities (i.e. %5B and %5D to []).
     */
    private String fileName;
    private String mimeType;
    private String hashValue;
    private String xpathPrefix;
    
    /**
     * The values as it is in the XML. All entities are preserved.
     */
    private String rawFileName;
    
    /**
     * Parent form name of which this attachment belongs
     */
    private String parentFormName;
    
    
    /* Constructor(s) */
    
    public AttachmentDetails() {}
    
    /**
     * 
     * @param contentID: att:href attribute value
     * @param fileName: attFileName element value
     * @param mimeType: att:MimeType element value
     * @param hashValue: glob:HashValue attribute value
     * @param fullFileName: xpath + att:FileName element value
     */
    public AttachmentDetails( String contentID, String fileName, String mimeType, String hashValue, String xpathPrefix ) {
    	this.contentID = contentID;
    	this.fileName = fileName;
    	this.mimeType = mimeType;
    	this.hashValue = hashValue;
    	this.xpathPrefix = xpathPrefix;
    }
    
    
    
    /* Public Method(s) */
    
    public String toString() { return ToStringBuilder.reflectionToString( this ); }
    
    /**
     * Convenience method that returns <code>xpathPrefix</code> + <code>fileName</code>
     * @return
     */
    public String getFullFileName() {
    	StringBuilder sb = new StringBuilder();
    	boolean hasPrefix = false;
    	if ( StringUtils.isNotBlank( this.xpathPrefix ) ) {
    		sb.append( this.xpathPrefix );
    		hasPrefix = true;
    	}// if
    	
    	if ( StringUtils.isNotBlank( this.fileName ) ) {
    		if ( hasPrefix ) {
    			sb.append( "-" );
    		}// if
    		sb.append( this.fileName );
    	}// if
    	
    	return sb.toString();
    }// getFullFileName
    
    public String getFullFileName(String updatedFileName) {
    	StringBuilder sb = new StringBuilder();
    	boolean hasPrefix = false;
    	if ( StringUtils.isNotBlank( this.xpathPrefix ) ) {
    		sb.append( this.xpathPrefix );
    		hasPrefix = true;
    	}// if
    	
    	if ( StringUtils.isNotBlank( updatedFileName ) ) {
    		if ( hasPrefix ) {
    			sb.append( "-" );
    		}// if
    		sb.append( updatedFileName );
    	}// if
    	
    	return sb.toString();
    }// getFullFileName
    
    /**
     * Return URL decoded file name
     * 
     * @return
     * @throws Exception
     */
    public String getUrlDecodedFileName() throws Exception {
    	String value = null;
    	try {
			value = GDGEscapeUtil.urlEncodeReservedUrlEncodeChars( this.fileName );
			value = URLDecoder.decode( value, CommonsGlobals.PREFERRED_ENCODING );
			
    	} catch ( Exception e ) {
    		log.error( e );
    		e.printStackTrace();
    		throw e;
    		
    	}// try-catch
    	
		return value;
		
    }// getUrlDecodedFileName
    
    
    /**
     * Return URL decoded content ID value
     * 
     * @return
     * @throws Exception
     */
    public String getUrlDecodedContentID() throws Exception {
    	String value = null;
    	try {
			value = GDGEscapeUtil.urlEncodeReservedUrlEncodeChars( this.contentID );
			value = URLDecoder.decode( value, CommonsGlobals.PREFERRED_ENCODING );
			
    	} catch ( Exception e ) {
    		log.error( e );
    		e.printStackTrace();
    		throw e;
    		
    	}// try-catch
    	
		return value;
		
    }// getUrlDecodedContentID
    
    
    /* Getters & Setters */

    /**
     * @return Returns the contentID.
     */
    public String getContentID() {
        return contentID;
    }

    /**
     * @param contentID The contentID to set.
     */
    public void setContentID(String contentID) {
        this.contentID = contentID;
    }

    /**
     * @return Returns the mimeType.
     */
    public String getMimeType() {
        return mimeType;
    }

    /**
     * @param mimeType The mimeType to set.
     */
    public void setMimeType(String mimeType) {
        this.mimeType = mimeType;
    }



	/**
	 * @return the fileName
	 */
	public String getFileName() {
		return fileName;
	}



	/**
	 * @param fileName the fileName to set
	 */
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}



	/**
	 * @return the hashValue
	 */
	public String getHashValue() {
		return hashValue;
	}



	/**
	 * @param hashValue the hashValue to set
	 */
	public void setHashValue(String hashValue) {
		this.hashValue = hashValue;
	}

	/**
	 * @return the xpathPrefix
	 */
	public String getXpathPrefix() {
		return xpathPrefix;
	}

	/**
	 * @param xpathPrefix the xpathPrefix to set
	 */
	public void setXpathPrefix(String xpathPrefix) {
		this.xpathPrefix = xpathPrefix;
	}

	/**
	 * @return the parentFormName
	 */
	public String getParentFormName() {
		return parentFormName;
	}

	/**
	 * @param parentFormName the parentFormName to set
	 */
	public void setParentFormName(String parentFormName) {
		this.parentFormName = parentFormName;
	}

	public String getRawFileName() {
		return rawFileName;
	}

	public void setRawFileName(String rawFileName) {
		this.rawFileName = rawFileName;
	}

}