package com.heckmansoft.surjey.model.manager;

import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import com.heckmansoft.surjey.model.datastore.DatastoreException;
import com.heckmansoft.surjey.model.datastore.SectionDatastore;
import com.heckmansoft.surjey.model.datastore.Transaction;
import com.heckmansoft.surjey.model.vo.Question;
import com.heckmansoft.surjey.model.vo.Section;
import com.heckmansoft.surjey.model.vo.lazy.LazySection;
import com.heckmansoft.surjey.model.vo.list.ValueObjectList;

/**
 * Manages Section objects.
 */
public class SectionManager extends SectionDatastore
{
    private Logger log = Logger.getLogger(SectionManager.class);

    private QuestionManager questionManager;

    public SectionManager() {
        super();
        this.questionManager = new QuestionManager();
    }

    /**
     * Creates a particular section.
     *
     * @param section Section instance containing updated data.
     * @return true if section is found and updated.
     */
    public boolean insert(Section section) throws DatastoreException {
        log.debug("create(" + section + ")");

        Transaction transaction = getTransaction();

        // Create the section
        boolean status = super.insert(section);
        String sectionId = section.getId();

        // Create all subordinate questions
        if (! section.questionsIsNull()) {
            ValueObjectList questions = section.getQuestions();

            Iterator iterator = questions.iterator();
            while(iterator.hasNext()) {
                Question question = (Question) iterator.next();
                question.setSectionId(sectionId);
            }

            status &= questionManager.insert(questions);
        }

        transaction.finish(status);

        return status;
    }

    /**
     * Updates a particular section.
     *
     * @param section Section instance containing updated data.
     * @return true if section is found and updated.
     */
    public boolean update(Section section) throws DatastoreException {
        log.debug("update(" + section + ")");

        Transaction transaction = getTransaction();

        // Update the section
        boolean status = super.update(section);
        String sectionId = section.getId();

        // Update all subordinate questions
        if (! section.questionsIsNull()) {
            ValueObjectList questions = section.getQuestions();

            Iterator iterator = questions.iterator();
            while(iterator.hasNext()) {
                Question question = (Question) iterator.next();
                question.setSectionId(sectionId);
            }

            status &= questionManager.update(questions);
        }

        transaction.finish(status);

        return status;
    }

    /**
     * Removes all sections for a given survey.
     * @param id Id of survey for which sections are to be removed
     * @return true if all matching sections are found and removed
     */
    public boolean removeBySurveyId(String id) throws DatastoreException {
        log.debug("removeBySurveyId(" + id + ")");

        // Get list of sections to remove
        List list = findBySurveyId(id);

        // If no sections to remove, we are done
        if (list.size() == 0) return true;

        Transaction transaction = getTransaction();

        // Remove sections
        boolean status = super.removeBySurveyId(id);

        // Remove questions for each section
        Iterator listIterator = list.iterator();
        while(listIterator.hasNext()) {
            Section section = (Section) listIterator.next();
            status &= questionManager.removeBySectionId(section.getId());
        }

        transaction.finish(status);

        return status;
    }

    /**
     * Removes given section.
     *
     * @param section Section to be removed.
     * @return true if a matching section is found and removed
     */
    public boolean remove(Section section) throws DatastoreException {
        return remove(section.getId());
    }

    /**
     * Removes section with given id.
     *
     * @param id Id of Section instance to be removed.
     * @return true if section is found and removed.
     */
    public boolean remove(String id) throws DatastoreException {
        log.debug("remove(" + id + ")");

        Transaction transaction = getTransaction();

        // Remove the section
        boolean status = super.remove(id);

        // Remove all subordinate questions
        status &= questionManager.removeBySectionId(id);

        transaction.finish(status);

        return status;
    }

    /**
     * For a given section id, get the subordinate questions.
     * @param id Section id to get the questions for.
     * @return List of questions in section
     */
    public ValueObjectList getQuestions(String id) throws DatastoreException {
        return questionManager.findBySectionId(id);
    }

    /**
     * Create a new section.
     * @return newly created section.
     */
    public Section createSection() {
        return new LazySection(this);
    }

    /**
     * Create a new section.
     * @return newly created section.
     */
    public Section createSection(String surveyId) throws DatastoreException {
        Section section = createSection();

        // Set the position and survey id
        section.setPosition(getNextPosition(surveyId));
        section.setSurveyId(surveyId);

        return section;
    }

    /**
     * Lookup position of next section
     */
    private String getNextPosition(String surveyId) throws DatastoreException {
        int nextPosition = 1;
        List sections = findBySurveyId(surveyId);
        int size = sections.size();
        if (size > 0) {
            Section lastSection = (Section) sections.get(size - 1);
            nextPosition += Integer.parseInt(lastSection.getPosition());
        }

        return String.valueOf(nextPosition);
    }

}
