/*
 * JORAM: Java(TM) Open Reliable Asynchronous Messaging
 * Copyright (C) 2013 - 2021 ScalAgent Distributed Technologies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA.
 *
 * Initial developer(s): ScalAgent Distributed Technologies
 * Contributor(s):
 */
package fr.dyade.aaa.util;

import java.io.File;
import java.io.IOException;

import org.junit.Assert;
import org.junit.Test;

import fr.dyade.aaa.ext.NGTransaction;

/**
 * This test highlights a bad behavior of txlog when using the create operation (see JMQ-215).
 * This bug could be present in the other transaction modules but only manifests itself with
 * the transaction grouping specific to txlog and batchengine.
 */
public class CreateTest {
  
  @Test
  public void test1() throws Exception {
    byte[] bytes = new byte[100];
    String name = "nameOfTheObject";
    String logpath = "./target/createTestTxDir1";
    
    delete(new File(logpath));
    
    NGTransaction transaction = new NGTransaction();
    transaction.init(logpath);
 
    transaction.createByteArray(bytes, name);
    transaction.begin();
    transaction.commit(true);
    
    for (int i=0; i<10; i++) {
      bytes = new byte[100];
      transaction.saveByteArray(bytes, name);
      transaction.begin();
      transaction.commit(true);
    }
    
    transaction.delete(name);
    transaction.begin();
    transaction.commit(true);

    bytes = new byte[100];
    transaction.saveByteArray(bytes, name);
    transaction.begin();
    transaction.commit(true);
    
    transaction.garbage(0);
    
    transaction.delete(name);
    transaction.createByteArray(bytes, name);
    transaction.begin();
    transaction.commit(true);
    
    transaction.delete(name);
    transaction.begin();
    transaction.commit(true);

    transaction.garbage(0);
    // Waits to avoid a divide by zero in close if init and close run in the same millisecond.
    Thread.sleep(1);
    transaction.close();

    transaction.init(logpath);
    bytes = transaction.loadByteArray(name);
    
    Assert.assertNull(bytes);

    // Waits to avoid a divide by zero in close if init and close run in the same millisecond.
    Thread.sleep(1);
    transaction.close();
  }
  
  public static void delete(File f) throws IOException {
    if (! f.exists()) return;
    
    if (f.isDirectory()) {
      for (File c : f.listFiles())
        delete(c);
    }
    
    if (!f.delete())
      throw new IOException("Failed to delete file: " + f);
  }
}
