package leigh.chain.directory;

import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;
import org.junit.jupiter.api.Test;

import java.time.Instant;
import java.time.temporal.ChronoUnit;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class DirectoryStateMachineTest {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(DirectoryStateMachineTest.class);

    @Test
    public void testInvalidExpiry() {
        DirectoryStore ds = new RamDirectoryStore();
        DirectoryStateMachine dsm = new DirectoryStateMachine(ds);
        String testName = "l";
        String testAddr = "0x52";
        String serviceUrl = "http://svc.l.c/service.json";

        Instant when = Instant.now();

        dsm.processNameClaim(testAddr, testName, 0,
                serviceUrl, when);
        Identity id = ds.getIdentityByName(testName, when);
        assert (id == null);

        dsm.processNameClaim(testAddr, testName, 7*31,
                serviceUrl, when);
        id = ds.getIdentityByName(testName, when);
        assert (id == null);

    }

    @Test
    public void testNameExpire() {
        DirectoryStore ds = new RamDirectoryStore();
        DirectoryStateMachine dsm = new DirectoryStateMachine(ds);
        String testName = "l";
        String testAddr = "0x52";
        String serviceUrl = "http://svc.l.c/service.json";

        Instant when = Instant.now();

        dsm.processNameClaim(testAddr, testName, 14,
                serviceUrl, when);

        Identity id = ds.getIdentityByName(testName, when);
        assert (id != null);

        id = ds.getIdentityByName(testName, when.plus(15, ChronoUnit.DAYS));
        assert (id == null);
    }

    @Test
    public void testBasicClaim() {
        DirectoryStore ds = new RamDirectoryStore();
        DirectoryStateMachine dsm = new DirectoryStateMachine(ds);
        String testName = "l";
        String testAddr = "0x52";
        String serviceUrl = "http://svc.l.c/service.json";

        Instant when = Instant.now();

        dsm.processNameClaim(testAddr, testName, 14,
                serviceUrl, when);

        // Make sure the naming took
        Identity id = ds.getIdentityByName(testName, when);
        assert (id != null);
        assertEquals(testName, id.getName());
        assertEquals(serviceUrl, id.getServiceUrl());

        id = ds.getIdentityByAddr(testAddr);
        assert (id != null);
        assertEquals(testName, id.getName());
        assertEquals(serviceUrl, id.getServiceUrl());

        logger.info("DSM state: {}", dsm);
    }
}
