package gov.va.vinci.dart.dms.biz;

import gov.va.vinci.dart.json.ErrorListView;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public abstract class ContentHelper {
	private static Log log = LogFactory.getLog(ContentHelper.class);

	
	public static ErrorListView copyContent(final Repository srcRepo, final Repository dstRepo, final boolean updateDocs) throws FileNotFoundException, IOException, GeneralSecurityException {

		// call this method within a Hibernate transaction
		// this may take a while to complete so cross your fingers that we don't have an exception and have to roll back.
		
		ErrorListView result = new ErrorListView("Error");
		
		InputStream is = null;
		
		// get the starting list
		List<Content> srcList = Content.listByRepository(srcRepo.getId());
		
		// loop through the list
		for (Content srcContent : srcList) {

			try {
				// create a new content object
				Content newContent = Content.create(srcContent.getTypeSuffix(), dstRepo.getId());
				
				if( updateDocs == true ) {
					
					// now alert the document that owns srcContent that it should point at a new content
					
					// find the list of documents that point at the original content
					List<Document> docList = Document.listByContentId(srcContent.getId());
					for (Document doc : docList) {
						
						// and point them at the new content
						doc.setContent(newContent);
					}

					// note that this will leave the original content object and file stranded.
				}//end if
				
				// and actually copy the file
				is = srcContent.openStream(false);
				newContent.write(is, false);	
				is.close();
				
			} catch(FileNotFoundException exc) {
				result.getErrors().add(exc.getMessage());
				
			} finally {

				if( is != null ) {
					try {
						is.close();
					} catch(IOException e) {
						log.error("Error closing stream: " + e.getMessage());
					}
				}
			}
				
		}//end for


		if (result.getErrors().size()< 1) {
			result.setMsg("OK");
		}

		return result;
	}
	

	public static ErrorListView copyContentBatch(final Repository srcRepo, final Repository dstRepo, final boolean updateDocs, int numToCopy) throws FileNotFoundException, IOException, GeneralSecurityException {

		// call this method within a Hibernate transaction
		// this may take a while to complete so cross your fingers that we don't have an exception and have to roll back.
		
		ErrorListView result = new ErrorListView("Error");
		
		InputStream is = null;
		
		// get the starting list
		List<Content> srcList = Content.listByRepository(srcRepo.getId());
		if( srcList != null ) {
		
			// loop through the list
			int i = 0;
			for (Content srcContent : srcList) {
				if( srcContent.getMappedContent() == null ) {	//no mapped content yet
				
					if( i < numToCopy ) {
	
						try {
							// create a new content object
							Content newContent = Content.create(srcContent.getTypeSuffix(), dstRepo.getId());

							newContent.setMappedContent(srcContent);
							srcContent.setMappedContent(newContent);
							
							if( updateDocs == true ) {
								
								// now alert the document that owns srcContent that it should point at a new content
								
								// find the list of documents that point at the original content
								List<Document> docList = Document.listByContentId(srcContent.getId());
								for (Document doc : docList) {
									
									// and point them at the new content
									doc.setContent(newContent);
								}
			
								// note that this will leave the original content object and file stranded.
							}//end if
							
							// and actually copy the file
							is = srcContent.openStream(false);
							newContent.write(is, false);	
							is.close();
							
						} catch(FileNotFoundException exc) {
							result.getErrors().add(exc.getMessage());
							
						} finally {

							if( is != null ) {
								try {
									is.close();
								} catch(IOException e) {
									log.error("Error closing stream: " + e.getMessage());
								}
							}

						}
	
						
						i++;
					}//end if

				}//end if -- no mappedContent
			}//end for

		}//end if

		if (result.getErrors().size()< 1) {
			result.setMsg("OK");
		}

		return result;
	}
	
	
	public static ErrorListView updateDocContent(final Repository srcRepo, final int numToCopy) throws FileNotFoundException, IOException, GeneralSecurityException {

		// call this method within a Hibernate transaction
		// this may take a while to complete so cross your fingers that we don't have an exception and have to roll back.

		ErrorListView result = new ErrorListView("Error");

		// get the starting list
		List<Content> srcList = Content.listByRepository(srcRepo.getId());
		if( srcList != null ) {
		
			// loop through the list
			int i = 0;
			for (Content srcContent : srcList) {
				if( srcContent.getMappedContent() != null ) {	//mapped content
				
					if( i < numToCopy ) {
	
						try {

								// now alert the document that owns srcContent that it should point at a new content

								// find the list of documents that point at the original content
								List<Document> docList = Document.listByContentId(srcContent.getId());
								if( docList != null && docList.size() > 0 ) {

									for (Document doc : docList) {
	
										// and point them at the new content
										doc.setContent( srcContent.getMappedContent() );
									}
									
									i++;	//updated
								}//end if

								// note that this will leave the original content object and file stranded.

						} catch(Exception exc) {
							result.getErrors().add(exc.getMessage());

						}
					}//end if

				}//end if -- mapped content
			}//end for

		}//end if

		if (result.getErrors().size()< 1) {
			result.setMsg("OK");
		}

		return result;
	}
	
	
	public static ErrorListView copyContentToken(final Repository srcRepo, final Repository dstRepo, final boolean updateDocs) throws FileNotFoundException, IOException, GeneralSecurityException {

		// call this method within a Hibernate transaction
		// this may take a while to complete so cross your fingers that we don't have an exception and have to roll back.
		
		ErrorListView result = new ErrorListView("Error");
		
		InputStream is = null;
		
		// get the starting list
		List<Content> srcList = Content.listByRepository(srcRepo.getId());
		
		// loop through the list
		for (Content srcContent : srcList) {

			try {
				// copy the content object
				Content newContent = Content.copy(srcContent, dstRepo.getId());
				
				if( updateDocs == true ) {
					
					// now alert the document that owns srcContent that it should point at a new content
					
					// find the list of documents that point at the original content
					List<Document> docList = Document.listByContentId(srcContent.getId());
					for (Document doc : docList) {
						
						// and point them at the new content
						doc.setContent(newContent);
					}
				
					// note that this will leave the original content object and file stranded.
				}//end if
				
				// and actually copy the file
				is = srcContent.openStream(false);
				newContent.write(is, false);	
				is.close();
				
			} catch(FileNotFoundException exc) {
				result.getErrors().add(exc.getMessage());

			} finally {

				if( is != null ) {
					try {
						is.close();
					} catch(IOException e) {
						log.error("Error closing stream: " + e.getMessage());
					}
				}
			}
				
		}//end for


		if (result.getErrors().size()< 1) {
			result.setMsg("OK");
		}

		return result;
	}

	// should we have a "prune dead content from repository" method?
	
}
