/** 
 * 
 * Copyright 2004 Hiram Chirino
 * 
 * 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.codehaus.activemq.journal.impl;

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

import junit.framework.TestCase;

import org.codehaus.activemq.journal.InvalidRecordLocationException;


/**
 * Tests the LogFile used by JournalImpl 
 * 
 * @version $Revision: 1.1 $
 */
public class LogFileTest extends TestCase {
	
    int size = 1024*512;
    int segmentCount=4;
    File logDirectory = new File("test-logfile");
	private LogFile logFile;
    
    /**
     * @see junit.framework.TestCase#setUp()
     */
    protected void setUp() throws Exception {
        if( logDirectory.exists() ) {
        	deleteDir(logDirectory);
        }
        assertTrue( !logDirectory.exists() );
        logFile = new LogFile(logDirectory,segmentCount,size);
    }

    /**
	 */
	private void deleteDir(File f) {
		File[] files = f.listFiles();
		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			file.delete();
		}
		f.delete();
	}

	protected void tearDown() throws Exception {
		logFile.close();
        if( logDirectory.exists() )
        	deleteDir(logDirectory);
        assertTrue( !logDirectory.exists() );
    }
    
    public void testLogFileCreation() throws IOException {
    	assertTrue( logFile.isSegmentIndexActive((byte)0) );
    	assertEquals( logFile.getAppendSegmentIndex(), (byte)0);
    	assertTrue( logFile.canActivateNextSegment() );
    	assertEquals( -1, logFile.getLastSequenceId());
    }
    
    public void testAppendAndRead() throws IOException, InvalidRecordLocationException {

    	appendHelloRecord(1001);    		
    	RecordLocationImpl loc = new RecordLocationImpl((byte)0, logFile.getAppendSegmentIndex(), logFile.getAppendSegmentOffset());			
    	appendHelloRecord(2002);
    	appendHelloRecord(3003);
    	
    	RecordLocationImpl loc2 = logFile.readRecordLocation(loc);
    	assertEquals( loc2.getSequenceId(), 2002 );
    	loc2 = logFile.getNextDataRecordLocation(loc2);
    	assertEquals( loc2.getSequenceId(), 3003 );
    	loc2 = logFile.getNextDataRecordLocation(loc2);
    	assertNull(loc2 );
    	
    }
    
    public void testRollOver() throws IOException, InvalidRecordLocationException {

    	int counter=0;
    	for( int i=0; i < segmentCount; i++ ) {
    		counter += 500;
        	appendHelloRecord(counter);
        	if( i+1==segmentCount ) {
            	assertFalse( logFile.canActivateNextSegment() );
        	} else {
            	assertTrue( logFile.getAppendSegmentIndex()==i );
            	assertTrue( logFile.canActivateNextSegment() );
            	logFile.activateNextSegment();
            	assertTrue( logFile.getAppendSegmentIndex()==i+1 );
        	}
    	}
    	
    	    	
    }
    

	/**
	 * @param i
	 * @throws IOException
	 */
	private void appendHelloRecord(int i) throws IOException {
		byte data[] = ("Hello World: "+i).getBytes();
		
        BatchedWrite write = new BatchedWrite(ByteBuffer.allocate(1024));
        Record batchedRecord = new Record((long)i, LogFile.DATA_RECORD_TYPE, data, null);
        write.append(batchedRecord);
		logFile.appendAndForce(write);
	}
}
