package jp.ac.osaka_u.ist.sel.similarity.hash.database;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import jp.ac.osaka_u.ist.sel.similarity.database.AbstractDAO;
import jp.ac.osaka_u.ist.sel.similarity.database.ColumnName;
import jp.ac.osaka_u.ist.sel.similarity.database.SQLGenerator;
import jp.ac.osaka_u.ist.sel.similarity.database.TableType;
import jp.ac.osaka_u.ist.sel.similarity.database.TransactionManager;

/**
 * DAO class for information of files.
 * 
 * @author ysk-ssk
 *
 */
public class SelectionFileDAO extends AbstractDAO {
	private Map<Integer,FileInfo> _fileIdToInfoMapping = new HashMap<Integer,FileInfo>();
	// heap size: (32 bit + 1KB) * n

	public SelectionFileDAO(TransactionManager transactionManager)
			throws SQLException {
		super(transactionManager);
		initializeIdToNameMapping();
	}
	
	/**
	 * Caching file IDs.
	 * 
	 * @throws SQLException
	 */
	private void initializeIdToNameMapping() throws SQLException {
		// create sql
		ColumnName[] columns = {ColumnName.ID,ColumnName.EXT,ColumnName.FILE_SIZE};
		String sql = SQLGenerator.getSelectStatement(TableType.FILE_INFO, columns);
		// prepare the statement
		PreparedStatement pstmt = prepareStatement(sql);
		// execute
		ResultSet results = executeQuery(pstmt);
		while (results.next()) {
			int fileId = results.getInt(1);
			String ext = results.getString(2);
			long size = results.getLong(3);
			FileInfo fileInfo = new FileInfo(ext,size);
			_fileIdToInfoMapping.put(fileId,fileInfo);
		}
	}
	
	public Set<Integer> getFileIdSet() {
		return _fileIdToInfoMapping.keySet();
	}
	
	public String getFilePath(int fileId) throws SQLException {
		assert(_fileIdToInfoMapping.get(fileId) != null);
        ColumnName[] columns = {ColumnName.PATH};
        String sql = SQLGenerator.getWhereSelectStatement(TableType.FILE_INFO, columns, ColumnName.ID, String.valueOf(fileId));
        PreparedStatement pstmt = prepareStatement(sql);
        ResultSet results = executeQuery(pstmt);
        if (!results.next()) {
            return null;
        }
        String path = results.getString(1);
        return path;
	}
	
	public String getFileExt(int fileId) {
		assert(_fileIdToInfoMapping.get(fileId) != null);
		return _fileIdToInfoMapping.get(fileId)._ext;
	}
	
    public long getFileSize(int fileId) {
        assert(_fileIdToInfoMapping.get(fileId) != null);
        return _fileIdToInfoMapping.get(fileId)._size;
    }
    
	private class FileInfo {
		public final String _ext;
		public final long _size;
		// heap size: String + long = 2 bytes * String.MAX_SIZE + 8 bytes
		
        public FileInfo(String ext, long size) {
            super();
            this._ext = ext;
            this._size = size;
        }

	}
}
