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.Section;
import com.heckmansoft.surjey.model.vo.ValueObject;
import com.heckmansoft.surjey.model.vo.list.ValueObjectList;

/**
 * Manages object-relational mapping for Section objects.
 */
public class SectionDatastore extends Datastore {
    final static String TABLE_NAME = "sections";
    final static String TABLE_ADD_FIELDS = "description, position, survey_id";
    final static String TABLE_PARENT_ID_FIELD = "survey_id";

    String parentIdField;

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

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

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

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

    /**
     * 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 + ")");
        ValueObjectList target = findBySurveyId(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);
        Section section = (Section) vo;
        args.add(section.getDescription());
        args.add(Integer.valueOf(section.getPosition()));
        args.add(Integer.valueOf(section.getSurveyId()));
        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 section
            Section section = createSection();
            super.extract(results, section);

            section.setDescription(results.getString("description"));
            section.setPosition(results.getString("position"));
            section.setSurveyId(results.getString("survey_id"));

            return section;

        } catch (SQLException e) {
            log.debug(e);
            throw new RuntimeException(e);
        }
    }

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

}
