/*
 * Copyright 2015-present 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));
    }
}
