/*
 * MAE - Multi-purpose Annotation Environment
 *
 * Copyright Keigh Rim (krim@brandeis.edu)
 * Department of Computer Science, Brandeis University
 * Original program by Amber Stubbs (astubbs@cs.brandeis.edu)
 *
 * MAE is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, @see <a href="http://www.gnu.org/licenses">http://www.gnu.org/licenses</a>.
 *
 * For feedback, reporting bugs, use the project on Github
 * @see <a href="https://github.com/keighrim/mae-annotation">https://github.com/keighrim/mae-annotation</a>.
 */

package edu.brandeis.llc.mae.database;

import com.j256.ormlite.support.ConnectionSource;
import edu.brandeis.llc.mae.MaeException;
import edu.brandeis.llc.mae.io.MaeIODTDException;
import edu.brandeis.llc.mae.model.*;
import edu.brandeis.llc.mae.util.MappedSet;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by krim on 12/27/2015.
 */
public interface MaeDriverI {

    void setupDatabase(ConnectionSource source) throws MaeDBException;

    void emptyAnnotations() throws MaeDBException;

    void destroy() throws MaeDBException;

    // task
    void readTask(File file) throws MaeDBException, MaeIODTDException, FileNotFoundException;

    String getTaskName() throws MaeDBException;

    void setTaskName(String value) throws MaeDBException;

    String readAnnotation(File file) throws MaeException;

    String getTaskFileName() throws MaeDBException;

    void setTaskFileName(String fileName) throws MaeDBException;

    String getDBSourceName();

    String getAnnotationFileName() throws MaeDBException;

    String getAnnotationFileBaseName() throws MaeDBException;

    void setAnnotationFileName(String fileName) throws MaeDBException;

    String getPrimaryText() throws MaeDBException;

    void setPrimaryText(String text) throws MaeDBException;

    boolean isTaskLoaded();

    boolean isAnnotationLoaded();

    void setAnnotationChanged(boolean b);

    boolean isAnnotationChanged();

    boolean isPrimaryTextLoaded();

    // character index (anchor)
    void batchCreateAnchors(Collection<CharIndex> anchors) throws MaeDBException;

    Collection<CharIndex> getAllAnchors() throws MaeDBException;

    Collection<CharIndex> getAllAnchorsOfTagType(TagType type) throws MaeDBException;

    List<Integer> getAllAnchorLocations() throws MaeDBException;

    List<Integer> getAllAnchorLocationsOfTagType(TagType type) throws MaeDBException;

    List<Integer> getAllAnchorLocationsOfTagType(TagType type, List<TagType> exculdes) throws MaeDBException;

    Collection<CharIndex> getAnchorsByTid(String tid) throws MaeDBException;

    List<Integer> getAnchorLocationsByTid(String tid) throws MaeDBException;

    // tag types
    TagType createTagType(String name, String prefix, boolean isLink) throws MaeDBException;

    List<TagType> getAllTagTypes() throws MaeDBException; // return list to keep inserted order (when read DTD, tagtypes are inserted to DB in order of their appearances in DTD)

    List<TagType> getExtentTagTypes() throws MaeDBException;

    List<TagType> getLinkTagTypes() throws MaeDBException;

    TagType getTagTypeByName(String name) throws MaeDBException;

    boolean setTagTypePrefix(TagType tagType, String prefix) throws MaeDBException;

    boolean setTagTypeNonConsuming(TagType tagType, boolean b) throws MaeDBException;

    // tag common
    Tag getTagByTid(String tid) throws MaeDBException;

    TagType getTagTypeByTid(String tid) throws MaeDBException;

    String getNextId(TagType type); // auto generation of proper ID of a given tag type

    // extent tags
    ExtentTag createExtentTag(String tid, TagType tagType, String text, int[] spans) throws MaeDBException;
    // create one using existing tid (e.g. reading from annotation xml)

    ExtentTag createExtentTag(TagType tagType, String text, int[] spans) throws MaeDBException;
    // create one with autogenerated tid (need auto generation inside driver impl)

    void batchCreateExtentTags(Collection<ExtentTag> tags) throws MaeDBException;

    boolean updateTagSpans(ExtentTag tag, int[] spans) throws MaeDBException;

    boolean updateTagText(ExtentTag tag, String text) throws MaeDBException;

    List<ExtentTag> getTagsAt(int location) throws MaeDBException;

    List<ExtentTag> getTagsIn(int[] locations) throws MaeDBException;

    List<ExtentTag> getTagsOfTypeAt(TagType type, int location) throws MaeDBException;

    List<ExtentTag> getTagsOfTypeIn(TagType type, int[] locations) throws MaeDBException;

    List<ExtentTag> getTagsOfTypeBetween(TagType type, int begin, int end) throws MaeDBException;

    MappedSet<TagType,ExtentTag> getTagsByTypesAt(int location) throws MaeDBException;

    MappedSet<TagType,ExtentTag> getTagsByTypesIn(int[] locations) throws MaeDBException;

    MappedSet<TagType,ExtentTag> getTagsByTypesBetween(int begin, int end) throws MaeDBException;

    List<ExtentTag> getAllExtentTagsOfAllTypes(boolean consumingOnly) throws MaeDBException;

    Collection<ExtentTag> lazilyGetAllExtentTagsOfType(TagType type) throws MaeDBException;

    Collection<ExtentTag> getAllExtentTagsOfType(TagType type) throws MaeDBException;

    List<ExtentTag> getAllNCTagsOfType(TagType type) throws MaeDBException;

    // link tags
    LinkTag createLinkTag(String tid, TagType tagType) throws MaeDBException;

    LinkTag createLinkTag(TagType tagType) throws MaeDBException;

    void batchCreateLinkTags(Collection<LinkTag> tags) throws MaeDBException;

    List<LinkTag> getAllLinkTagsOfAllTypes() throws MaeDBException;

    Collection<LinkTag> lazilyGetAllLinkTagsOfType(TagType type) throws MaeDBException;

    Collection<LinkTag> getAllLinkTagsOfType(TagType type) throws MaeDBException;

    void deleteTag(Tag tag) throws MaeDBException;

    Set<LinkTag> getLinksHasArgumentTag(ExtentTag argument) throws MaeDBException;

    // att types
    AttributeType createAttributeType(TagType linktag, String from) throws MaeDBException;

    AttributeType getAttributeTypeOfTagTypeByName(TagType type, String name) throws MaeDBException;

    List<AttributeType> getAttributeTypesOfTagType(TagType type) throws MaeDBException;

    MappedSet<String, String> getTagTypesAndAttTypes() throws MaeDBException;

    void setAttributeTypeValueSet(AttributeType type, List<String> validValues) throws MaeDBException;

    void setAttributeTypeDefaultValue(AttributeType type, String defaultValue) throws MaeDBException;

    void setAttributeTypeIDRef(AttributeType type, boolean b) throws MaeDBException;

    void setAttributeTypeRequired(AttributeType type, boolean b) throws MaeDBException;

    // atts
    Attribute addAttribute(Tag tag, AttributeType attType, String attValue) throws MaeDBException;

    void batchCreateAttributes(Collection<Attribute> atts) throws MaeDBException;

    void batchCreateArguments(Collection<Argument> args) throws MaeDBException;

    Set<Attribute> batchAddAttributes(Tag tag, Map<AttributeType, String> attributes) throws MaeDBException;

    Attribute updateAttribute(Tag tag, AttributeType attType, String attValue) throws MaeDBException;

    void deleteAttribute(Tag tag, AttributeType attType) throws MaeDBException;

    Map<Tag, Map<String, String>> getAttributeMapsOfTagType(TagType type) throws MaeDBException;

    Map<String, String> getAttributeMapOfTag(Tag tag) throws MaeDBException;

    // arg types
    ArgumentType createArgumentType(TagType linktag, String from) throws MaeDBException;

    ArgumentType getArgumentTypeOfTagTypeByName(TagType type, String name) throws MaeDBException;

    List<ArgumentType> getArgumentTypesOfLinkTagType(TagType link) throws MaeDBException;

    void setArgumentTypeRequired(ArgumentType type, boolean b) throws MaeDBException;

    // args
    Argument addArgument(LinkTag linker, ArgumentType argType, ExtentTag argument) throws MaeDBException;

    Argument UpdateArgument(LinkTag linker, ArgumentType argType, ExtentTag argument) throws MaeDBException;

}
