package com.dragonsoft.tryapp.ejb.entity;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;

import com.dragonsoft.tryapp.common.exceptions.ExceptionHandler;
import com.dragonsoft.tryapp.common.exceptions.TryException;
import com.dragonsoft.tryapp.common.exceptions.TryIOException;
import com.dragonsoft.tryapp.ejb.entity.interfaces.CourseKey;
import com.dragonsoft.tryapp.ejb.entity.utils.CourseFSUtils;
import com.dragonsoft.tryapp.ejb.entity.utils.FileSystemTraverser;
import com.dragonsoft.tryapp.support.TryFileSystem;

/**
 * @ejb.bean name="CourseFS"
 *           display-name="Name for CourseFS"
 *           description="Description for CourseFS"
 *           jndi-name="ejb/CourseFS"
 *           type="BMP"
 *           view-type="both"
 * 			 primkey-field="key"
 */
public class CourseFSBean implements EntityBean {

	private static final FileSystemTraverser traverser = new FileSystemTraverser();
	private static CourseKey key; // empty but for xdoclet only.
	private static final String COURSENAME = "COURSENAME.fire";
	private EntityContext ctx;
	private String courseNumber;
	private String section;
	private String term;
	private String name;

	/**
	 * 
	 */
	public CourseFSBean() {
		super();
	}

	/* (non-Javadoc)
	 * @see javax.ejb.EntityBean#setEntityContext(javax.ejb.EntityContext)
	 */
	public void setEntityContext(EntityContext ctx)
		throws EJBException,
		RemoteException {
		this.ctx = ctx;

	}

	/* (non-Javadoc)
	 * @see javax.ejb.EntityBean#unsetEntityContext()
	 */
	public void unsetEntityContext() throws EJBException, RemoteException {
		this.ctx = null;
	}

	/* (non-Javadoc)
	 * @see javax.ejb.EntityBean#ejbRemove()
	 */
	public void ejbRemove()
		throws RemoveException,
		EJBException,
		RemoteException {
		FileSystemTraverser traverser = new FileSystemTraverser();
		CourseKey key = (CourseKey) ctx.getPrimaryKey();
		File[] files = null;
		try{
			File root = traverser.getCourseDirectory(key);//new File(CourseFSUtils.getPath(key.getTerm(), key.getCourseNum(), key.getSection()));
			System.out.println(root.getAbsolutePath());
			if(root.isDirectory()){
				try {
					TryFileSystem.rmdir(root);
				} catch (TryIOException e) {
					ExceptionHandler.logException(e,this);
					throw new RemoveException(e.getMessage());
				}
			}
		}catch(TryException e){
			ExceptionHandler.logException(e,this);
			throw new RemoveException(e.getMessage());
		}
	}
	
	
	

	/* (non-Javadoc)
	 * @see javax.ejb.EntityBean#ejbActivate()
	 */
	public void ejbActivate() throws EJBException, RemoteException {

	}

	/* (non-Javadoc)
	 * @see javax.ejb.EntityBean#ejbPassivate()
	 */
	public void ejbPassivate() throws EJBException, RemoteException {

	}

	/* (non-Javadoc)
	 * @see javax.ejb.EntityBean#ejbLoad()
	 */
	public void ejbLoad() throws EJBException, RemoteException {
		CourseKey key = (CourseKey) ctx.getPrimaryKey();
		this.term = key.getTerm();
		this.courseNumber = key.getCourseNum();
		this.section = key.getSection();

		File fileDir = getDirectory();
		if (!fileDir.exists()) {
			throw new EJBException("Course Does not Exist");
		}
		File coursename = new File(fileDir,COURSENAME);
		try {
			BufferedReader reader = new BufferedReader(new FileReader(
				coursename));
			this.name = reader.readLine();
			reader.close();
		} catch (FileNotFoundException e) {
			throw new EJBException("Corrupted Course: " + fileDir.getName(), e);
		} catch (IOException e) {
			throw new EJBException("Corrupted Course: " + fileDir.getName(), e);
		}
	}

	/* (non-Javadoc)
	 * @see javax.ejb.EntityBean#ejbStore()
	 */
	public void ejbStore() throws EJBException, RemoteException {
		//String path = getPath();
		File dir = getDirectory();//new File(path);
		if (!dir.exists()) {
			if (!dir.mkdirs()) {
				throw new EJBException("Cannot Save to File System: " + dir.getName());
			}
		}
		File coursename = new File(dir,COURSENAME);
		if (!coursename.exists()) {
			try {
				if (!coursename.createNewFile()) {
					throw new IOException("Could not create File");
				}
			} catch (IOException e) {
				throw new EJBException("Error while persisting Course", e);
			}
		}
		try {
			FileWriter writer = new FileWriter(coursename);
			writer.write(name);
			writer.flush();
			writer.close();
		} catch (IOException e) {
			throw new EJBException("Could not Create FileName", e);
		}

	}

	/**
	 * Create method
	 * @ejb.create-method  view-type = "both"
	 */
	public com.dragonsoft.tryapp.ejb.entity.interfaces.CourseKey ejbCreate(
		String term,
		String courseNumber,
		String name) throws javax.ejb.CreateException {
		this.term = term;
		this.name = name;
		this.courseNumber = courseNumber;
		File file = getDirectory();//new File(getPath());
		if (file.exists()) {
			throw new CreateException(
				"The Course you wish to create, already exists.");
		}
		return new CourseKey(term, courseNumber);
	}
	/**
	 * Post Create method
	 */
	public void ejbPostCreate(String term, String courseNumber, String name)
		throws javax.ejb.CreateException {

	}

	/**
	 * Create method
	 * @ejb.create-method  view-type = "both"
	 */
	public com.dragonsoft.tryapp.ejb.entity.interfaces.CourseKey ejbCreate(
		String term,
		String courseNumber,
		String section,
		String name) throws javax.ejb.CreateException {
		this.term = term;
		this.courseNumber = courseNumber;
		this.name = name;
		this.section = section;
		File file = getDirectory();//new File(getPath());
		if (file.exists()) {
			throw new EJBException(
				"The Course you wish to create, already exists.");
		}
		return new CourseKey(term, courseNumber, section);
	}

	/**
	 * Post Create method
	 */
	public void ejbPostCreate(
		String term,
		String courseNumber,
		String section,
		String name) throws javax.ejb.CreateException {

	}
	/*
	 * Gets the path on the filesystem where the course should be located.
	 */
	private File getDirectory() {
		File rtVal = null;
		try {
			rtVal =traverser.getCourseDirectory(new CourseKey(this.term,this.courseNumber,this.section));//CourseFSUtils.getPath(this.term, this.courseNumber, this.section);
		} catch (TryException e) {
			ExceptionHandler.logException(e,this);
		}
		return rtVal;
	}

	/**
	 * Gets the Course Name associated with the Course.
	 * Business method
	 * @ejb.interface-method  view-type = "both"
	 */
	public String getCourseName() {
		return this.name;
	}
	/**
	 * Gets the Course Number associated with the course.
	 * Business method
	 * @ejb.interface-method  view-type = "both"
	 */
	public String getCourseNumber() {
		return this.courseNumber;
	}
	/**
	 * Gets the term associated with the course.
	 * Business method
	 * @ejb.interface-method  view-type = "both"
	 */
	public String getTerm() {
		return this.term;
	}
	/**
	 * Gets the Section of the Course 
	 * Business method
	 * @ejb.interface-method  view-type = "remote"
	 */
	public String getSection() {
		return this.section;
	}
	/**
	 * Business method
	 * @ejb.interface-method  view-type = "both"
	 */
	public void setCourseName(String name) {
		this.name = name;
	}

	/**
	 * 
	 * @param key
	 * @return
	 * @throws FinderException
	 */
	public CourseKey ejbFindByPrimaryKey(CourseKey key) throws FinderException {
		return key;
	}

	/**
	 * 
	 * @param term
	 * @return
	 * @throws FinderException
	 */
	public Collection ejbFindByTerm(String term) throws FinderException {
		List lst = new ArrayList();
		
		String path = "";
		try {
			path = TryFileSystem.getAssignmentDirectory()+term;
		
			File coursesDir = new File(path);
		//		 	this means that there are courses in the term
			if(coursesDir.exists()){
				File[] courses = coursesDir.listFiles();
				for(int i =0;i<courses.length;i++){
					if(courses[i].isDirectory()){
						lst.addAll(ejbFindByCourseNumber(courses[i].getName()));
					}
				}
			
			}
			else throw new TryException("Invalid Term");
		} catch (TryException e) {
			ExceptionHandler.logException(e,this);
			throw new FinderException("Cannot find any Courses." + e.getMessage());
		}
		if(lst.size() ==0)
			throw new FinderException("Empty Term");
		return lst;
	}

	/**
	 * Find by Coursenumber. Traverse file structure for the correct course
	 * number.
	 * @param courseNumber the coursenum to be searched for.
	 * @return a collection of CourseKeys which contains information for all
	 * courses(main and individual sections) which correspond to the coursenumber.
	 * @throws FinderException If nothing is found.
	 */
	public Collection ejbFindByCourseNumber(String courseNumber)
		throws FinderException {
		List lst = new ArrayList();
		try {
			String path = TryFileSystem.getAssignmentDirectory();
			File file = new File(path);
			File[] terms;
			File[] courses;
			File[] sections;
			File swap;
			if(file.isDirectory()){
				terms = file.listFiles();
				for(int i = 0;i<terms.length;i++){
					if(terms[i].isDirectory()){
						courses = terms[i].listFiles();
						for(int k =0;k<courses.length;k++){
							if(courses[k].getName().equals(courseNumber)){
								swap = new File(courses[k].getAbsolutePath()+File.pathSeparator+CourseFSUtils.SECTIONS);
								if(swap.exists() && swap.isDirectory()){
									sections = swap.listFiles();
									for(int l = 0;l<sections.length;l++){
										if(sections[l].isDirectory()){
											lst.add(new CourseKey(terms[i].getName(),courses[k].getName(),sections[l].getName()));
										}
									}
								}
								lst.add(new CourseKey(terms[i].getName(),courses[k].getName()));
								System.out.println("FOUND IT in one year");
							}
						}
					}
				}
			}
			
		} catch (TryException e) {
			throw new FinderException("Could not find due to complications");
		}
		if(lst.size() == 0){
			throw new FinderException("The CourseNumber: "+courseNumber+" Dones not exist.");
		}
		return lst;
	}

	/**
	 * Business method
	 * @ejb.interface-method  view-type = "both"
	 */
	public CourseKey getKey() {
		return new CourseKey(term,courseNumber,section);
	}
	
}
