/* Copyright (C) 2009  CSE,IIT Bombay  http://www.cse.iitb.ac.in

This file is part of the ConStore open source storage facility for concept-nets.

ConStore is free software and distributed under the 
Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License;
you can copy, distribute and transmit the work
with the work attribution in the manner specified by the author or licensor.
You may not use this work for commercial purposes and may not alter, 
transform, or build upon this work.

Please refer the legal code of the license, available at
http://creativecommons.org/licenses/by-nc-nd/3.0/legalcode

ConStore 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.  */

package iitb.con.ds;

import iitb.con.core.ConStoreConstants;
import iitb.con.io.BufferedFileAdapter;
import iitb.con.io.IOAdapter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;

/**
 * Factory class to create the Instance Table which holds the instance meta item ({@link InstanceMetaItem})
 * It maintains a single instance of Instance Table.
 * 
 * @author Prathab K
 *
 */
public class InstanceTableFactory {
    
    /** Instance Table handle */
    private static InstanceTable instanceTable = null;
                                            

    /** Returns the Instance Table 
     * @param dirName directory name of the concept-net
     * @param mode opening mode (r, rw)
     * @return Instance Table
     * @see ItemTable
     */
    public static ItemTable<Short, Integer, InstanceMetaItem>
                        getInstanceTable(String dirName, String mode){
        if(instanceTable == null) {
            createInstanceTable(dirName, mode);
        }
        return instanceTable;
    }
    
    /**
     * Shutdowns the Instance Table factory.
     * <p>This method is used to close the concept-net</p>
     */
    public static void shutDown() {
        instanceTable = null;
    }
    
    
    /**
     * Creates the instance table. It is constructed with {@link InstanceMetaItem} as the value objects
     * and with type id and instance id as keys.
     * @param dirName directory name of the concept-net
     * @param mode opening mode (r, rw)
     */
    private static void createInstanceTable(String dirName, String mode) {
        try {
            String fileName = dirName + ConStoreConstants.INSTANCE_TABLE_FILE;
            instanceTable = new InstanceTable(dirName, mode);
            File file = new File(fileName);
            int length = (int)file.length();
            IOAdapter instanceTableFile = new BufferedFileAdapter(fileName, "r", length);
            ByteBuffer buffer = instanceTableFile.readIntoBuffer(0);
            buffer.rewind();
            short size = InstanceMetaItem.headerSize();
            byte[] b = new byte[size];
            while (buffer.hasRemaining()) {
                long itemLocation = buffer.position();
                buffer.get(b);
                ItemSerializer instanceTableSerializer = new InstanceTableSerializer();
                InstanceMetaItem item = 
                    (InstanceMetaItem) instanceTableSerializer.deSerialize(ByteBuffer.wrap(b));
                item.itemLocation = itemLocation;
                //TODO: optimize the performance without wrapping the bytes
                instanceTable.setItem(item.typeId,item.instanceId, item);
            }
            instanceTableFile.close();
        }catch(FileNotFoundException fe){
            fe.printStackTrace();
        }catch(IOException ie) {
            ie.printStackTrace();
        }
    }
}