package server.servlets;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;

/**
 * The CourseDataFileReader class encapsulates the functionality
 * required to read information from the course CSV file, extract the
 * data and populate an array of Course objects which can then
 * be used to more easilay manipulate the course information stored
 * in the CSV file.
 *
 * @author Robert Lysik
 * @version 1.00
 */
class CourseDataFileReader {
    public Course[] courses;

    /**
     * The CourseDataFileReader constructor opens the CSV
     * file and extracts the data. This data is parsed and
     * formatted in order to construct an array of Course objects
     * which can then be more easily manipulated.
     */
    CourseDataFileReader() {
        Vector fileRowVector;
        Vector courseVector;

        // Extract a vector of rows from the CSV file
        fileRowVector = readCourseDataFile();

        // Parse through each row of the file and construct an
        // array of Course objects.
        courseVector = processCourseDataFileRows(fileRowVector);

        courses = new Course[courseVector.size()];

        for (int index = 0; index < courseVector.size(); index++)
            courses[index] = (Course) courseVector.get(index);
    }

    /**
     * This function takes a vector of row data obtained from the
     * CSV course file and returns a vecor of Course objects which
     * are the result of parsing this data for Course related
     * information. Each course has an id, a section id, a term,
     * a year, an instructor and a list of Students.
     *
     * @param Vector a vector of rows obtained from the CSV file
     */
    private Vector processCourseDataFileRows(Vector fileRowVector) {
        CsvLineParser parser = new CsvLineParser();
        Vector courseVector = new Vector();
        String[] values;
        boolean courseFound = false;
        int courseIndex = 0;
        String courseId = new String();
        String sectionId = new String();
        String term = new String();
        String year = new String();
        String name = new String();

        for (int fileRowIndex = 1;
             fileRowIndex < fileRowVector.size();
             fileRowIndex++) {
            values = parser.getTokens((String) fileRowVector.get(fileRowIndex));

            courseId = values[1];
            sectionId = values[2];
            term = values[4];
            year = values[5];
            name = values[8] + " " + values[9];

            courseFound = courseExists(courseId, sectionId, courseVector);

            if (!courseFound) {
                Vector studentVector = new Vector();

                String[] valArray;


                for (int index = 1; index < fileRowVector.size(); index++) {
                    valArray = parser.getTokens((String) fileRowVector.get(index));

                    if ((courseId.equals(valArray[1])) &&
                            (sectionId.equals(valArray[2]))) {

                        Student student = new Student(valArray[15],
                                valArray[16],
                                valArray[17],
                                Integer.parseInt(valArray[12]));
                        studentVector.add(student);
                    }
                }

                Student[] students = new Student[studentVector.size()];

                for (int index = 0; index < studentVector.size(); index++)
                    students[index] = (Student) studentVector.get(index);

                Course course = new Course(courseId,
                        sectionId,
                        term,
                        year,
                        name,
                        students);
                courseVector.add(course);
            }
        }

        return courseVector;
    }

    /**
     * This function is used to determine if a specific course
     * exists in the array of Course objects.
     *
     * @param String the course id
     * @param String the section id of the course
     * @param Vector the vector of Course objects to check for the
     *               existence of the course within.
     */
    private boolean courseExists(String courseId,
                                 String sectionId,
                                 Vector courseVector) {
        boolean exists = false;
        Course course;
        String course_id = new String();
        String section_id = new String();

        for (int index = 0; index < courseVector.size(); index++) {
            course = (Course) courseVector.get(index);

            course_id = course.getCourseId();
            section_id = course.getSectionId();

            if ((courseId.equals(course_id)) &&
                    (sectionId.equals(section_id))) {
                exists = true;

                break;
            }
        }

        return exists;
    }

    /**
     * This function reads the course data CSV file and
     * returns a Vector of row data.
     */
    private Vector readCourseDataFile() {
        FileReader reader = null;
        Vector fileRowVector = new Vector();

        try {
            reader = new FileReader("c:\\formc.csv");
        } catch (FileNotFoundException fnfe) {
            fnfe.printStackTrace();
        }

        try {
            String row = new String();
            char buffer = ' ';
            int readValue = 0;

            readValue = reader.read();

            while (readValue != -1) {
                buffer = (char) readValue;

                while ((buffer != '\n') && (readValue != -1)) {
                    row += buffer;

                    readValue = reader.read();

                    buffer = (char) readValue;
                }

                fileRowVector.add(row);

                row = "";

                readValue = reader.read();
            }

            reader.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

        return fileRowVector;
    }

    /**
     * This function returns the array of Course objects obtained
     * by parsing the course data CSV file.
     */
    public Course[] getCourses() {
        return courses;
    }

    /**
     * This function returns the Course object which matches
     * the course id and section id passed in as parameters.
     *
     * @param String the course id
     * @param String the section id of the course
     */
    public Course getCourse(String courseId,
                            String sectionId) {
        boolean courseFound = false;
        int index = 0;
        Course course = null;

        while ((!courseFound) && (index < courses.length)) {
            if (courseId.equals(courses[index].getCourseId()) &&
                    (sectionId.equals(courses[index].getSectionId())))
                courseFound = true;
            else
                index++;
        }

        if (courseFound)
            return courses[index];

        return course;
    }

    /**
     * This function returns an array of course ids
     * which correspond to all the unique course ids of
     * the array of Course objects.
     */
    public String[] getCourseIds() {
        String[] courseIds = new String[courses.length];

        for (int index = 0; index < courses.length; index++)
            courseIds[index] = courses[index].getCourseId();

        return courseIds;
    }

    /**
     * This function returns an array of section ids
     * which correspond to the course id passed in as a parameter.
     *
     * @param String the course id
     */
    public String[] getSectionIds(String courseId) {
        Vector sectionVector = new Vector();

        for (int index = 0; index < courses.length; index++)
            if (courseId.equals(courses[index].getCourseId()))
                sectionVector.add(courses[index].getSectionId());

        String[] sectionIds = new String[sectionVector.size()];

        for (int index = 0; index < sectionVector.size(); index++)
            sectionIds[index] = (String) sectionVector.get(index);

        return sectionIds;
    }

    /**
     * This function returns the name of the instructor
     * for the Course which matches the course id and section
     * id passed in as parameters.
     *
     * @param String the course id
     * @param String the section id of the course
     */
    public String getCourseInstructor(String courseId,
                                      String sectionId) {
        int index = 0;
        boolean courseFound = false;
        String instructor = new String();

        while ((!courseFound) && (index < courses.length)) {
            if (courseId.equals(courses[index].getCourseId()) &&
                    (sectionId.equals(courses[index].getSectionId())))
                courseFound = true;
            else
                index++;
        }

        if (courseFound)
            instructor = courses[index].getInstructor();

        return instructor;
    }

    /**
     * This function returns the an array of Students which
     * are associated with the Course that matches the course id
     * and section id passed in as parameters.
     *
     * @param String the course id
     * @param String the section id of the course
     */
    public Student[] getCourseStudents(String courseId,
                                       String sectionId) {
        int index = 0;
        boolean courseFound = false;
        Student[] empty = null;

        while ((!courseFound) && (index < courses.length)) {
            if (courseId.equals(courses[index].getCourseId()) &&
                    (sectionId.equals(courses[index].getSectionId())))
                courseFound = true;
            else
                index++;
        }

        if (courseFound)
            return courses[index].getStudents();

        return empty;
    }
}