/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.onosproject.net.intent;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.core.IdGenerator;
import org.onosproject.store.Timestamp;

import com.google.common.testing.EqualsTester;

import static junit.framework.TestCase.assertFalse;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertTrue;
import static org.onosproject.net.intent.IntentTestsMocks.MockIntent;
import static org.onosproject.net.intent.IntentTestsMocks.MockTimestamp;

/**
 * Unit tests for intent data objects.
 */
public class IntentDataTest {

    private Timestamp timestamp1;
    private Timestamp timestamp2;
    private Timestamp timestamp3;

    private Intent intent1;
    private Intent intent2;
    private Intent intent3;

    private IntentData data1;
    private IntentData data1Copy;
    private IntentData data2;
    private IntentData data2Copy;
    private IntentData data3;
    private IntentData data3Copy;

    IdGenerator idGenerator;

    @Before
    public void setUpTest() {
        idGenerator = new MockIdGenerator();
        Intent.bindIdGenerator(idGenerator);

        timestamp1 = new MockTimestamp(1);
        timestamp2 = new MockTimestamp(2);
        timestamp3 = new MockTimestamp(3);

        intent1 = new MockIntent(1L);
        intent2 = new MockIntent(2L);
        intent3 = new MockIntent(3L);

        data1 = new IntentData(intent1, IntentState.INSTALLED, timestamp1);
        data1Copy = new IntentData(intent1, IntentState.INSTALLED, timestamp1);
        data2 = new IntentData(intent2, IntentState.INSTALLED, timestamp2);
        data2Copy = new IntentData(intent2, IntentState.INSTALLED, timestamp2);
        data3 = new IntentData(intent3, IntentState.INSTALLED, timestamp3);
        data3Copy = new IntentData(intent3, IntentState.INSTALLED, timestamp3);
    }

    @After
    public void tearDownTest() {
        Intent.unbindIdGenerator(idGenerator);
    }

    /**
     * Checks that intent data objects are properly constructed.
     */
    @Test
    public void checkConstruction() {
        assertThat(data1.state(), is(IntentState.INSTALLED));
        assertThat(data1.version(), is(timestamp1));
        assertThat(data1.intent(), is(intent1));
    }

    /**
     * Checks equals() for intent data objects.
     */
    @Test
    public void checkEquals() {
        new EqualsTester()
                .addEqualityGroup(data1, data1Copy)
                .addEqualityGroup(data2, data2Copy)
                .addEqualityGroup(data3, data3Copy)
                .testEquals();
    }

    @Test
    public void testIsUpdateAcceptable() {
        // Going from null to something is always allowed
        assertTrue(IntentData.isUpdateAcceptable(null, data1));

        // we can go from older version to newer but not they other way
        assertTrue(IntentData.isUpdateAcceptable(data1, data2));
        assertFalse(IntentData.isUpdateAcceptable(data2, data1));

        IntentData installing = new IntentData(intent1, IntentState.INSTALLING, timestamp1);
        IntentData installed = new IntentData(intent1, IntentState.INSTALLED, timestamp1);
        IntentData withdrawing = new IntentData(intent1, IntentState.WITHDRAWING, timestamp1);
        IntentData withdrawn = new IntentData(intent1, IntentState.WITHDRAWN, timestamp1);

        IntentData failed = new IntentData(intent1, IntentState.FAILED, timestamp1);
        IntentData purgeReq = new IntentData(intent1, IntentState.PURGE_REQ, timestamp1);

        IntentData compiling = new IntentData(intent1, IntentState.COMPILING, timestamp1);
        IntentData recompiling = new IntentData(intent1, IntentState.RECOMPILING, timestamp1);
        IntentData installReq = new IntentData(intent1, IntentState.INSTALL_REQ, timestamp1);
        IntentData withdrawReq = new IntentData(intent1, IntentState.WITHDRAW_REQ, timestamp1);

        // We can't change to the same state
        assertFalse(IntentData.isUpdateAcceptable(installing, installing));
        assertFalse(IntentData.isUpdateAcceptable(installed, installed));

        // From installing we can change to installed
        assertTrue(IntentData.isUpdateAcceptable(installing, installed));

        // Sanity checks in case the manager submits bogus state transitions
        assertFalse(IntentData.isUpdateAcceptable(installing, withdrawing));
        assertFalse(IntentData.isUpdateAcceptable(installing, withdrawn));
        assertFalse(IntentData.isUpdateAcceptable(installed, withdrawing));
        assertFalse(IntentData.isUpdateAcceptable(installed, withdrawn));

        // We can't change to the same state
        assertFalse(IntentData.isUpdateAcceptable(withdrawing, withdrawing));
        assertFalse(IntentData.isUpdateAcceptable(withdrawn, withdrawn));

        // From withdrawing we can change to withdrawn
        assertTrue(IntentData.isUpdateAcceptable(withdrawing, withdrawn));

        // Sanity checks in case the manager submits bogus state transitions
        assertFalse(IntentData.isUpdateAcceptable(withdrawing, installing));
        assertFalse(IntentData.isUpdateAcceptable(withdrawing, installed));
        assertFalse(IntentData.isUpdateAcceptable(withdrawn, installing));
        assertFalse(IntentData.isUpdateAcceptable(withdrawn, installed));

        // We can't go from failed to failed
        assertFalse(IntentData.isUpdateAcceptable(failed, failed));

        // But we can go from any install* or withdraw* state to failed
        assertTrue(IntentData.isUpdateAcceptable(installing, failed));
        assertTrue(IntentData.isUpdateAcceptable(installed, failed));
        assertTrue(IntentData.isUpdateAcceptable(withdrawing, failed));
        assertTrue(IntentData.isUpdateAcceptable(withdrawn, failed));

        // We can go from anything to purgeReq
        assertTrue(IntentData.isUpdateAcceptable(installing, purgeReq));
        assertTrue(IntentData.isUpdateAcceptable(installed, purgeReq));
        assertTrue(IntentData.isUpdateAcceptable(withdrawing, purgeReq));
        assertTrue(IntentData.isUpdateAcceptable(withdrawn, purgeReq));
        assertTrue(IntentData.isUpdateAcceptable(failed, purgeReq));

        // We can't go from purgeReq back to anything else
        assertFalse(IntentData.isUpdateAcceptable(purgeReq, withdrawn));
        assertFalse(IntentData.isUpdateAcceptable(purgeReq, withdrawing));
        assertFalse(IntentData.isUpdateAcceptable(purgeReq, installed));
        assertFalse(IntentData.isUpdateAcceptable(purgeReq, installing));

        // We're never allowed to store transient states
        assertFalse(IntentData.isUpdateAcceptable(installing, compiling));
        assertFalse(IntentData.isUpdateAcceptable(installing, recompiling));
        assertFalse(IntentData.isUpdateAcceptable(installing, installReq));
        assertFalse(IntentData.isUpdateAcceptable(installing, withdrawReq));
    }
}
