package com.heckmansoft.surjey.model.datastore;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.heckmansoft.surjey.model.vo.Question;
import com.heckmansoft.surjey.model.vo.ValueObject;
import com.heckmansoft.surjey.model.vo.list.ValueObjectList;

/**
 * Manages object-relational mapping for Question objects.
 */
public class QuestionDatastore extends Datastore {
    final static String TABLE_NAME = "questions";
    final static String TABLE_ADD_FIELDS =
        "label, position, display_size, answer_labels, " +
        "section_id, question_type_id";

    final static String TABLE_PARENT_ID_FIELD = "section_id";

    String parentIdField;

    private Logger log = Logger.getLogger(QuestionDatastore.class);

    /**
     * Constructor.
     */
    public QuestionDatastore() {
        super(TABLE_NAME,TABLE_ADD_FIELDS);
        parentIdField = TABLE_PARENT_ID_FIELD;
    }

    /**
     * Finds a particular question.
     *
     * @param id the id of the question to find.
     * @return A Question instance, or null if no match found
     */
    public Question findById(String id) throws DatastoreException {
        log.debug("findById(" + id + ")");
        return ((Question) extractSingle(selectById(id)));
    }

    /**
     * Finds all questions for a particular section.
     *
     * @param id Id of the section containing the questions to find.
     * @return A list of matching Question instances
     */
    public ValueObjectList findBySectionId(String id) throws DatastoreException {
        log.debug("findBySectionId(" + id + ")");
        List args = new ArrayList();
        args.add(new Integer(id));
        return extractList(selectWhere(parentIdField + " = ?", args));
    }

    /**
     * Removes all questions for a given section.
     * @param id Id of section for which sections are to be removed.
     * @return true if all matching questions are found and removed
     */
    public boolean removeBySectionId(String id) throws DatastoreException {
        log.debug("removeBySectionId(" + id + ")");
        ValueObjectList target = findBySectionId(id);
        if (target.size() == 0) return true;
        return remove(target);
    }

    /**
     * From the given object, get a list of arguments to use for
     * constructing a query or update.
     * @param vo Object containing data to use.
     * @return A list of arguments.
     */
    protected List getArgs(ValueObject vo) {
        List args = super.getArgs(vo);
        Question question = (Question) vo;
        args.add(question.getLabel());
        args.add(question.getPosition());
        args.add(question.getDisplaySize());
        args.add(question.getAnswerLabels());
        args.add(Integer.valueOf(question.getSectionId()));
        args.add(Integer.valueOf(question.getQuestionTypeId()));
        return args;
    }

    /**
     * Extract an object from the given result set.
     * @param results The result set.
     * @return The newly extracted object.
     */
    protected ValueObject extract(ResultSet results) throws DatastoreException {
        try{
            // Create a new question
            Question question = createQuestion();
            super.extract(results, question);

            // Insert properties from the current row of the result set
            question.setLabel(results.getString("label"));
            question.setPosition(results.getString("position"));
            question.setDisplaySize(results.getString("display_size"));
            question.setSectionId(results.getString("section_id"));
            question.setQuestionTypeId(results.getString("question_type_id"));
            question.setAnswerLabels(results.getString("answer_labels"));

            return question;

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Create a new question.
     * @return newly created question.
     */
    protected Question createQuestion() {
        return new Question();
    }

}
