/*
 * Sleuth Kit Data Model
 *
 * Copyright 2011-2016 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sleuthkit.datamodel;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * Interface for all datatypes that can be found in the database. Content
 * objects make up a tree and each object can have a parent and children. For
 * example, the child of an Image object is a Volume or File System. This
 * interface defines the basic methods for reading the content associated with
 * this object, the parent and children, and adding artifacts.
 */
public interface Content extends SleuthkitVisitableItem {

	/**
	 * Reads data that this content object is associated with (file contents,
	 * volume contents, etc.).
	 *
	 * @param buf    a character array of data (in bytes) to copy read data to
	 * @param offset byte offset in the content to start reading from
	 * @param len    number of bytes to read into buf.
	 *
	 * @return num of bytes read, or -1 on error
	 *
	 * @throws TskCoreException if critical error occurred during read in the
	 *                          tsk core
	 */
	public int read(byte[] buf, long offset, long len) throws TskCoreException;

	/**
	 * Free native resources after read is done on the Content object. After
	 * closing, read can be called again on the same Content object, which
	 * should result in re-opening of new native resources.
	 */
	public void close();

	/**
	 * Get the (reported) size of the content object and, in theory, how much
	 * you should be able to read from it. In some cases, data corruption may
	 * mean that you cannot read this much data.
	 *
	 * @return size of the content in bytes
	 */
	public long getSize();

	/**
	 * Visitor pattern support
	 *
	 * @param v visitor supplying an algorithm to run on the content object
	 *
	 * @return visitor return value resulting from running the algorithm
	 */
	public <T> T accept(ContentVisitor<T> v);

	/**
	 * Get the name of this content object (does not include parent path)
	 *
	 * @return the name
	 */
	public String getName();

	/**
	 * @return returns the full path to this Content object starting with a "/"
	 *         followed by the Image name and similarly for all other segments
	 *         in the hierarchy.
	 */
	public String getUniquePath() throws TskCoreException;

	/**
	 * Returns the unique object ID that was assigned to it in the database.
	 * This is a Sleuth Kit database-assigned number.
	 *
	 * @return object id
	 */
	public long getId();

	/**
	 * Gets the root data source (image, virtual directory, etc.) of this
	 * content.
	 *
	 * @return Content associated with data source or null if one can't be found
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public Content getDataSource() throws TskCoreException;

	/**
	 * Gets the child content objects of this content.
	 *
	 * @return List of children
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public List<Content> getChildren() throws TskCoreException;

	/**
	 * Returns true if the content object has children objects. Note, this
	 * should be more efficient than getting children and checking it empty.
	 *
	 * @return true if has children, false otherwise.
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public boolean hasChildren() throws TskCoreException;

	/**
	 * Returns count of children objects. Note, this should be more efficient
	 * than getting children and counting them.
	 *
	 * @return children count
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public int getChildrenCount() throws TskCoreException;

	/**
	 * @return returns the parent of this Content object or null if there isn't
	 *         one as is the case for Image.
	 *
	 * @throws TskCoreException
	 */
	public Content getParent() throws TskCoreException;

	/**
	 * Gets the child content ids of this content.
	 *
	 * @return List of children ids
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public List<Long> getChildrenIds() throws TskCoreException;

	/**
	 * Create and add an artifact associated with this content to the blackboard
	 *
	 * @param artifactTypeID id of the artifact type (if the id doesn't already
	 *                       exist an exception will be thrown)
	 *
	 * @return the blackboard artifact created (the artifact type id can be
	 *         looked up from this)
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 * @deprecated Please use newDataArtifact or newAnalysisResult.
	 */
	@Deprecated
	public BlackboardArtifact newArtifact(int artifactTypeID) throws TskCoreException;

	/**
	 * Create and add an artifact associated with this content to the blackboard
	 *
	 * @param type artifact enum tyoe
	 *
	 * @return the blackboard artifact created (the artifact type id can be
	 *         looked up from this)
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 * @deprecated Please use newDataArtifact or newAnalysisResult.
	 */
	@Deprecated
	public BlackboardArtifact newArtifact(BlackboardArtifact.ARTIFACT_TYPE type) throws TskCoreException;

	/**
	 * Create and add an analysis result associated with this content.
	 *
	 *
	 * @param artifactType	  Type of analysis result artifact to create.
	 * @param score          Score associated with this analysis.
	 * @param conclusion     Conclusion from the analysis, may be empty.
	 * @param configuration  Configuration element associated with this
	 *                       analysis, may be empty.
	 * @param justification	 Justification
	 * @param attributesList Additional attributes to attach to this analysis
	 *                       result artifact.
	 *
	 * @return AnalysisResultAdded The analysis return added and the current
	 *         aggregate score of content.
	 *
	 * @throws TskCoreException if critical error occurred within tsk core.
	 */
	public AnalysisResultAdded newAnalysisResult(BlackboardArtifact.Type artifactType, Score score, String conclusion, String configuration, String justification, Collection<BlackboardAttribute> attributesList) throws TskCoreException;

	/**
	 * Create and add an analysis result associated with this content.
	 *
	 *
	 * @param artifactType	  Type of analysis result artifact to create.
	 * @param score          Score associated with this analysis.
	 * @param conclusion     Conclusion from the analysis, may be empty.
	 * @param configuration  Configuration element associated with this
	 *                       analysis, may be empty.
	 * @param justification	 Justification
	 * @param attributesList Additional attributes to attach to this analysis
	 *                       result artifact.
	 * @param dataSourceId   The data source for the analysis result
	 *
	 * @return AnalysisResultAdded The analysis return added and the current
	 *         aggregate score of content.
	 *
	 * @throws TskCoreException if critical error occurred within tsk core.
	 */
	public AnalysisResultAdded newAnalysisResult(BlackboardArtifact.Type artifactType, Score score, String conclusion, String configuration, String justification, Collection<BlackboardAttribute> attributesList, long dataSourceId) throws TskCoreException;

	/**
	 * Create and add a data artifact associated with this abstract file. This
	 * method creates the data artifact with the os account id associated with
	 * this abstract file if one exists.
	 *
	 * @param artifactType   Type of data artifact to create.
	 * @param attributesList Additional attributes to attach to this data
	 *                       artifact.
	 *
	 * @return DataArtifact New data artifact.
	 *
	 * @throws TskCoreException If a critical error occurred within tsk core.
	 */
	public DataArtifact newDataArtifact(BlackboardArtifact.Type artifactType, Collection<BlackboardAttribute> attributesList) throws TskCoreException;
	
	
	/**
	 * Create and add a data artifact associated with this content.
	 *
	 * @param artifactType   Type of analysis result artifact to create.
	 * @param attributesList Additional attributes to attach to this data
	 *                       artifact.
	 * @param osAccountId    The OS account id associated with the artifact. May
	 *                       be null.
	 *
	 * @return DataArtifact New data artifact.
	 *
	 * @throws TskCoreException If a critical error occurred within tsk core.
	 */
	public DataArtifact newDataArtifact(BlackboardArtifact.Type artifactType, Collection<BlackboardAttribute> attributesList, Long osAccountId) throws TskCoreException;

	/**
	 * Create and add a data artifact associated with this content.
	 *
	 * @param artifactType   Type of analysis result artifact to create.
	 * @param attributesList Additional attributes to attach to this data
	 *                       artifact.
	 * @param osAccountId    The OS account id associated with the artifact. May
	 *                       be null.
	 * @param dataSourceId   The data source id of the artifact
	 *
	 * @return DataArtifact New data artifact.
	 *
	 * @throws TskCoreException If a critical error occurred within tsk core.
	 */
	public DataArtifact newDataArtifact(BlackboardArtifact.Type artifactType, Collection<BlackboardAttribute> attributesList, Long osAccountId, long dataSourceId) throws TskCoreException;

	/**
	 * Returns the final score for the content object.
	 *
	 * @return Score.
	 *
	 * @throws TskCoreException if critical error occurred within tsk core.
	 */
	public Score getAggregateScore() throws TskCoreException;

	/**
	 * Get all artifacts associated with this content that have the given type
	 * name
	 *
	 * @param artifactTypeName name of the type to look up
	 *
	 * @return a list of blackboard artifacts matching the type
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public ArrayList<BlackboardArtifact> getArtifacts(String artifactTypeName) throws TskCoreException;

	/**
	 * Get all analysis results associated with this content, that have the
	 * given type.
	 *
	 * @param artifactType Type to look up.
	 *
	 * @return A list of analysis result artifacts matching the type.
	 *
	 * @throws TskCoreException If critical error occurred within tsk core.
	 */
	public List<AnalysisResult> getAnalysisResults(BlackboardArtifact.Type artifactType) throws TskCoreException;

	/**
	 * Return the TSK_GEN_INFO artifact for the file so that individual
	 * attributes can be added to it. Creates one if it does not already exist.
	 *
	 * @return Instance of the TSK_GEN_INFO artifact
	 *
	 * @throws TskCoreException
	 */
	public BlackboardArtifact getGenInfoArtifact() throws TskCoreException;

	/**
	 * Return the TSK_GEN_INFO artifact for the file so that individual
	 * attributes can be added to it. If one does not create, behavior depends
	 * on the create argument.
	 *
	 * @param create If true, an artifact will be created if it does not already
	 *               exist.
	 *
	 * @return Instance of the TSK_GEN_INFO artifact or null if artifact does
	 *         not already exist and create was set to false
	 *
	 * @throws TskCoreException
	 */
	public BlackboardArtifact getGenInfoArtifact(boolean create) throws TskCoreException;

	/**
	 * Return attributes of a given type from TSK_GEN_INFO.
	 *
	 * @param attr_type Attribute type to find inside of the TSK_GEN_INFO
	 *                  artifact.
	 *
	 * @return Attributes
	 */
	public ArrayList<BlackboardAttribute> getGenInfoAttributes(BlackboardAttribute.ATTRIBUTE_TYPE attr_type) throws TskCoreException;

	/**
	 * Get all artifacts associated with this content that have the given type
	 * id
	 *
	 * @param artifactTypeID type id to look up
	 *
	 * @return a list of blackboard artifacts matching the type
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public ArrayList<BlackboardArtifact> getArtifacts(int artifactTypeID) throws TskCoreException;

	/**
	 * Get all artifacts associated with this content that have the given type
	 *
	 * @param type type to look up
	 *
	 * @return a list of blackboard artifacts matching the type
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public ArrayList<BlackboardArtifact> getArtifacts(BlackboardArtifact.ARTIFACT_TYPE type) throws TskCoreException;

	/**
	 * Get all artifacts associated with this content
	 *
	 * @return a list of blackboard artifacts
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public ArrayList<BlackboardArtifact> getAllArtifacts() throws TskCoreException;

	/**
	 * Get all data artifacts associated with this content.
	 *
	 * @return A list of data artifacts.
	 *
	 * @throws TskCoreException If critical error occurred within tsk core.
	 */
	public List<DataArtifact> getAllDataArtifacts() throws TskCoreException;
		
	/**
	 * Get all analysis results associated with this content.
	 *
	 * @return A list of analysis results.
	 *
	 * @throws TskCoreException If critical error occurred within tsk core.
	 */
	public List<AnalysisResult> getAllAnalysisResults() throws TskCoreException;

	/**
	 * Get the names of all the hashsets that this content is in.
	 *
	 * @return the names of the hashsets that this content is in
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public Set<String> getHashSetNames() throws TskCoreException;

	/**
	 * Get count of all artifacts associated with this content that have the
	 * given type name
	 *
	 * @param artifactTypeName name of the type to look up
	 *
	 * @return count of blackboard artifacts matching the type
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public long getArtifactsCount(String artifactTypeName) throws TskCoreException;

	/**
	 * Get count of all artifacts associated with this content that have the
	 * given type id
	 *
	 * @param artifactTypeID type id to look up
	 *
	 * @return count of blackboard artifacts matching the type
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public long getArtifactsCount(int artifactTypeID) throws TskCoreException;

	/**
	 * Get count of all artifacts associated with this content that have the
	 * given type
	 *
	 * @param type type to look up
	 *
	 * @return count of blackboard artifacts matching the type
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public long getArtifactsCount(BlackboardArtifact.ARTIFACT_TYPE type) throws TskCoreException;

	/**
	 * Get count of all artifacts associated with this content
	 *
	 * @return count of all blackboard artifacts for this content
	 *
	 * @throws TskCoreException if critical error occurred within tsk core
	 */
	public long getAllArtifactsCount() throws TskCoreException;
}
