/*
 * Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
 *
 * Licensed under the BSD License, see LICENSE file for details.
 *
 */

package org.xtreemfs.foundation.flease;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import junit.framework.TestCase;
import org.xtreemfs.foundation.TimeSync;
import org.xtreemfs.foundation.buffer.ASCIIString;
import org.xtreemfs.foundation.flease.comm.FleaseMessage;
import org.xtreemfs.foundation.flease.proposer.FleaseException;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.logging.Logging.Category;

/**
 *
 * @author bjko
 */
public class FleaseStageTest extends TestCase {

    private final FleaseConfig cfg;
    
    public FleaseStageTest(String testName) {
        super(testName);

        Logging.start(Logging.LEVEL_WARN, Category.all);
        TimeSync.initializeLocal(50);

        cfg = new FleaseConfig(10000, 500, 500, new InetSocketAddress(12345), "localhost:12345",5);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
    }

    /**
     * Test of createTimer method, of class FleaseStage.
     */
    public void testOpenAndGetLease() throws Exception {
        final ASCIIString CELL_ID = new ASCIIString("testcell");

        final AtomicReference<Flease> result = new AtomicReference();

        FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() {

            @Override
            public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
                //ignore me
            }
        }, true, new FleaseViewChangeListenerInterface() {

            @Override
            public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
            }
        },new FleaseStatusListener() {

            @Override
            public void statusChanged(ASCIIString cellId, Flease lease) {
                // System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder());
                synchronized (result) {
                    result.set(new Flease(cellId, lease.getLeaseHolder(), lease.getLeaseTimeout_ms(),lease.getMasterEpochNumber()));
                    result.notify();
                }
            }

            @Override
            public void leaseFailed(ASCIIString cellId, FleaseException error) {
                FleaseStageTest.fail(error.toString());
            }
        }, null);

        FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
        msg.setCellId(CELL_ID);

        fs.start();
        fs.waitForStartup();

        fs.openCell(CELL_ID, new ArrayList(),false);
       
        synchronized(result) {
            if (result.get() == null)
                result.wait(1000);
            if (result.get() == null)
                fail("timeout!");
        }

        assertEquals(result.get().getLeaseHolder(),cfg.getIdentity());

        FleaseFuture f = fs.closeCell(CELL_ID, false);
        f.get();

        Thread.sleep(12000);

        result.set(null);

        fs.openCell(CELL_ID, new ArrayList(), false);

        synchronized(result) {
            if (result.get() == null)
                result.wait(1000);
            if (result.get() == null)
                fail("timeout!");
        }

        assertEquals(result.get().getLeaseHolder(),cfg.getIdentity());

        fs.shutdown();
        fs.waitForShutdown();

    }


    /**
     * Test of createTimer method, of class FleaseStage.
     */
    public void testGetState() throws Exception {
        FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() {

            @Override
            public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
                //ignore me
            }
        }, true, new FleaseViewChangeListenerInterface() {

            @Override
            public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
            }
        },new FleaseStatusListener() {

            @Override
            public void statusChanged(ASCIIString cellId, Flease lease) {
            }

            @Override
            public void leaseFailed(ASCIIString cellId, FleaseException error) {
                FleaseStageTest.fail(error.toString());
            }
        }, null);

        FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
        msg.setCellId(new ASCIIString("testcell"));

        fs.start();
        fs.waitForStartup();

        FleaseFuture f = fs.openCell(new ASCIIString("testcell"), new ArrayList(), false);
        final AtomicBoolean done = new AtomicBoolean(false);
        f.get();
        
        Thread.sleep(100);


        Map<ASCIIString,FleaseMessage> m = fs.getLocalState();

        // for (ASCIIString cellId : m.keySet()) {
        // System.out.println("cell "+cellId+" "+m.get(cellId));
        // }

        fs.shutdown();
        fs.waitForShutdown();

    }

    /**
     * Test of createTimer method, of class FleaseStage.
     */
    public void testCreateTimer() throws Exception {
        FleaseStage fs = new FleaseStage(cfg, "/tmp/xtreemfs-test/", new FleaseMessageSenderInterface() {

            @Override
            public void sendMessage(FleaseMessage messages, InetSocketAddress recipient) {
                //ignore me
            }
        }, true, new FleaseViewChangeListenerInterface() {

            @Override
            public void viewIdChangeEvent(ASCIIString cellId, int viewId) {
            }
        },new FleaseStatusListener() {

            @Override
            public void statusChanged(ASCIIString cellId, Flease lease) {
                throw new UnsupportedOperationException("Not supported yet.");
            }

            @Override
            public void leaseFailed(ASCIIString cellId, FleaseException error) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        }, null);

        FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
        msg.setCellId(new ASCIIString("testcell"));

        fs.start();
        fs.waitForStartup();
        fs.createTimer(msg, TimeSync.getLocalSystemTime()+20);
        Thread.sleep(100);
        fs.shutdown();
        fs.waitForShutdown();

    }

}

@@ -181,16 +181,37 @@
 lease;%0A%0A
+import java.io.File;%0A
 import j
@@ -237,16 +237,16 @@
 ddress;%0A
-
 import j
@@ -740,16 +740,61 @@
 ategory;
+%0Aimport org.xtreemfs.foundation.util.FSUtils;
 %0A%0A/**%0A *
@@ -899,24 +899,52 @@
 ig cfg;%0A    
+private final File testDir;%0A
 %0A    public 
@@ -1200,16 +1200,67 @@
 45%22,5);%0A
+        testDir = new File(%22/tmp/xtreemfs-test/%22);%0A
     %7D%0A%0A 
@@ -1310,32 +1310,32 @@
 ows Exception %7B%0A
-
         super.se
@@ -1337,24 +1337,84 @@
 er.setUp();%0A
+        FSUtils.delTree(testDir);%0A        testDir.mkdirs();%0A
     %7D%0A%0A    @

create test directory before running FleaseStageTest