/*
 * 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.store.intent.impl;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.intent.HostToHostIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.MockIdGenerator;
import org.onosproject.net.intent.WorkPartitionServiceAdapter;
import org.onosproject.store.service.TestStorageService;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.hid;

/**
 * Gossip Intent Store test using database adapter.
 */
public class GossipIntentStoreTest {

    private GossipIntentStore intentStore;
    private IdGenerator idGenerator;
    private HostToHostIntent.Builder builder1;

    @Before
    public void setUp() {
        intentStore = new GossipIntentStore();
        intentStore.storageService = new TestStorageService();
        intentStore.partitionService = new WorkPartitionServiceAdapter();
        intentStore.clusterService = new ClusterServiceAdapter();
        idGenerator = new MockIdGenerator();
        Intent.bindIdGenerator(idGenerator);
        builder1 = HostToHostIntent
                        .builder()
                        .one(hid("12:34:56:78:91:ab/1"))
                        .two(hid("12:34:56:78:91:ac/1"))
                        .appId(APP_ID);
        intentStore.activate();
    }

    @After
    public void cleanUp() {
        intentStore.deactivate();
        Intent.unbindIdGenerator(idGenerator);
    }

    /**
     * Generates a list of test intent data.
     *
     * @param count how many intent data objects are needed
     * @return list of intent data
     */
    private List<IntentData> generateIntentList(int count) {
        LinkedList<IntentData> intents = new LinkedList<>();
        IntStream.rangeClosed(1, count)
                .forEach(i ->
                        intents.add(
                                new IntentData(
                                        builder1
                                                .priority(i)
                                                .build(),
                                        IntentState.INSTALLED,
                                        new IntentTestsMocks.MockTimestamp(12))));
        return intents;
    }

    /**
     * Tests the intent count APIs.
     */
    @Test
    public void testGetIntentCount() {
        assertThat(intentStore.getIntentCount(), is(0L));

        generateIntentList(5).forEach(intentStore::write);

        assertThat(intentStore.getIntentCount(), is(5L));
    }

    /**
     * Tests the batch add API.
     */
    @Test
    public void testBatchAdd() {
        assertThat(intentStore.getIntentCount(), is(0L));

        List<IntentData> intents = generateIntentList(5);

        intentStore.batchWrite(intents);
        assertThat(intentStore.getIntentCount(), is(5L));
    }


    /**
     * Tests adding and withdrawing an Intent.
     */
    @Test
    public void testAddAndWithdrawIntent() {
        // build and install one intent
        Intent intent = builder1.build();
        IntentData installed = new IntentData(
                intent,
                IntentState.INSTALLED,
                new IntentTestsMocks.MockTimestamp(12));
        intentStore.write(installed);

        // check that the intent count includes the new one
        assertThat(intentStore.getIntentCount(), is(1L));

        // check that the getIntents() API returns the new intent
        intentStore.getIntents()
                .forEach(item -> assertThat(item, is(intent)));

        // check that the getInstallableIntents() API returns the new intent
        intentStore.getInstallableIntents(intent.key())
                .forEach(item -> assertThat(item, is(intent)));

        // check that the getIntent() API can find the new intent
        Intent queried = intentStore.getIntent(intent.key());
        assertThat(queried, is(intent));

        // check that the state of the new intent is correct
        IntentState state = intentStore.getIntentState(intent.key());
        assertThat(state, is(IntentState.INSTALLED));

        // check that the getIntentData() API returns the proper value for the
        // new intent
        IntentData dataByQuery = intentStore.getIntentData(intent.key());
        assertThat(dataByQuery, is(installed));

        // check that the getIntentData() API returns the new intent when given
        // a time stamp to look for
        Iterable<IntentData> dataIteratorByTime = intentStore.getIntentData(true, 10L);
        assertThat(dataIteratorByTime.iterator().hasNext(), is(true));
        dataIteratorByTime.forEach(
                data -> assertThat(data, is(installed))
        );

        // check that the getIntentData() API returns the new intent when asked to
        // find all intents
        Iterable<IntentData> dataIteratorAll = intentStore.getIntentData(false, 0L);
        assertThat(dataIteratorAll.iterator().hasNext(), is(true));
        dataIteratorAll.forEach(
                data -> assertThat(data, is(installed))
        );

        // now purge the intent that was created
        IntentData purge = new IntentData(
                intent,
                IntentState.PURGE_REQ,
                new IntentTestsMocks.MockTimestamp(12));
        intentStore.write(purge);

        // check that no intents are left
        assertThat(intentStore.getIntentCount(), is(0L));

        // check that a getIntent() operation on the key of the purged intent
        // returns null
        Intent queriedAfterWithdrawal = intentStore.getIntent(intent.key());
        assertThat(queriedAfterWithdrawal, nullValue());
    }

    /**
     * Tests the operation of the APIs for the pending map.
     */
    @Test
    public void testPending() {
        // crete a new intent and add it as pending
        Intent intent = builder1.build();
        IntentData installed = new IntentData(
                intent,
                IntentState.INSTALLED,
                new IntentTestsMocks.MockTimestamp(11));
        intentStore.addPending(installed);

        // check that the getPending() API returns the new pending intent
        Iterable<Intent> pendingIntentIteratorAll = intentStore.getPending();
        assertThat(pendingIntentIteratorAll.iterator().hasNext(), is(true));
        pendingIntentIteratorAll.forEach(
                data -> assertThat(data, is(intent))
        );

        // check that the getPendingData() API returns the IntentData for the
        // new pending intent
        Iterable<IntentData> pendingDataIteratorAll = intentStore.getPendingData();
        assertThat(pendingDataIteratorAll.iterator().hasNext(), is(true));
        pendingDataIteratorAll.forEach(
                data -> assertThat(data, is(installed))
        );

        // check that the new pending intent is returned by the getPendingData()
        // API when a time stamp is provided
        Iterable<IntentData> pendingDataIteratorSelected =
                intentStore.getPendingData(true, 10L);
        assertThat(pendingDataIteratorSelected.iterator().hasNext(), is(true));
        pendingDataIteratorSelected.forEach(
                data -> assertThat(data, is(installed))
        );

        // check that the new pending intent is returned by the getPendingData()
        // API when a time stamp is provided
        Iterable<IntentData> pendingDataIteratorAllFromTimestamp =
                intentStore.getPendingData(false, 0L);
        assertThat(pendingDataIteratorAllFromTimestamp.iterator().hasNext(), is(true));
        pendingDataIteratorSelected.forEach(
                data -> assertThat(data, is(installed))
        );
    }
}
