/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.opencord.sadis.impl;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNull;

import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.opencord.sadis.BaseConfig;
import org.opencord.sadis.BaseInformation;
import org.opencord.sadis.BaseInformationService;
import org.opencord.sadis.SubscriberAndDeviceInformation;

/**
 * Set of tests of the SADIS ONOS application component.
 */
public class SubscriberAndDeviceManagerTest extends BaseSadis {

    @Before
    public void setUp() throws Exception {
        config = new SubscriberAndDeviceInformationConfig();
        super.setUp("/LocalSubConfig.json", SubscriberAndDeviceInformationConfig.class);
    }

    @After
    public void tearDown() {
        super.tearDown();
    }

    @Test
    public void testConfiguration() {
        SubscriberAndDeviceInformationConfig config = sadis.cfgService.getConfig(null,
                SubscriberAndDeviceInformationConfig.class);
        checkConfigInfo(50, "PT1m", config);
        checkEntriesForSubscriberAndAccessDevice(config);
    }

    private void checkEntriesForSubscriberAndAccessDevice(BaseConfig config) {
        List<SubscriberAndDeviceInformation> entries = config.getEntries();
        assertEquals(3, entries.size());
        assertTrue(checkEquality(entry1, entries.get(0)));
        assertTrue(checkEquality(entry2, entries.get(1)));
        assertTrue(checkEquality(entry5, entries.get(2)));
    }

    @Test
    public void testLocalMode() throws Exception {

        BaseInformationService<SubscriberAndDeviceInformation> subscriberService = sadis.getSubscriberInfoService();

        checkGetForExisting(ID1, entry1, subscriberService);
        checkGetForExisting(ID2, entry2, subscriberService);
        checkGetForExisting(ID5, entry5, subscriberService);

        invalidateId(ID1, subscriberService);
        checkFromBoth(ID1, entry1, subscriberService);

        invalidateAll(subscriberService);
        checkFromBoth(ID2, entry2, subscriberService);
    }


    private void checkGetForNonExist(String id, BaseInformationService service) {
        BaseInformation entry = service.get(id);
        assertNull(entry);
    }

    @Test
    public void testRemoteMode() throws Exception {
        BaseInformationService<SubscriberAndDeviceInformation> subscriberService = sadis.getSubscriberInfoService();
        config.init(subject, "sadis-remote-mode-test", node("/RemoteConfig.json"), mapper, delegate);
        configListener.event(event);

        checkGetForExisting(ID3, entry3, subscriberService);
        checkGetForExisting(ID4, entry4, subscriberService);

        invalidateId(ID3, subscriberService);
        checkFromBoth(ID3, entry3, subscriberService);

        invalidateAll(subscriberService);
        checkFromBoth(ID4, entry4, subscriberService);
    }

    @Test
    public void testModeSwitch() throws Exception {
        BaseInformationService<SubscriberAndDeviceInformation> service = sadis.getSubscriberInfoService();
        config.init(subject, "sadis-remote-mode-test", node("/RemoteConfig.json"), mapper, delegate);
        configListener.event(event);

        checkGetForExisting(ID3, null, service);
        checkGetForNonExist(ID1, service);

        config.init(subject, "sadis-local-mode-test", node("/LocalSubConfig.json"), mapper, delegate);
        configListener.event(event);

        checkGetForExisting(ID1, null, service);
        checkGetForNonExist(ID3, service);
    }



    public boolean checkEquality(BaseInformation localEntry, BaseInformation entry) {
        SubscriberAndDeviceInformation sub = (SubscriberAndDeviceInformation) localEntry;
        SubscriberAndDeviceInformation other = (SubscriberAndDeviceInformation) localEntry;

        if (other == null) {
            return false;
        }
        if (sub.hardwareIdentifier() == null) {
            if (other.hardwareIdentifier() != null) {
                return false;
            }
        } else if (!sub.hardwareIdentifier().equals(other.hardwareIdentifier())) {
            return false;
        }
        if (sub.id() == null) {
            if (other.id() != null) {
                return false;
            }
        } else if (!sub.id().equals(other.id())) {
            return false;
        }
        if (sub.nasPortId() == null) {
            if (other.nasPortId() != null) {
                return false;
            }
        } else if (!sub.nasPortId().equals(other.nasPortId())) {
            return false;
        }
        if (sub.nasId() == null) {
            if (other.nasId() != null) {
                return false;
            }
        } else if (!sub.nasId().equals(other.nasId())) {
            return false;
        }
        if (sub.ipAddress() == null) {
            if (other.ipAddress() != null) {
                return false;
            }
        } else if (!sub.ipAddress().equals(other.ipAddress())) {
            return false;
        }
        if (sub.uplinkPort() != other.uplinkPort()) {
            return false;
        }
        if (sub.slot() != other.slot()) {
            return false;
        }
        if (sub.circuitId() == null) {
            if (other.circuitId() != null) {
                return false;
            }
        } else if (!sub.circuitId().equals(other.circuitId())) {
            return false;
        }
        if (sub.remoteId() == null) {
            if (other.remoteId() != null) {
                return false;
            }
        } else if (!sub.remoteId().equals(other.remoteId())) {
            return false;
        }
        if (sub.uniTagList() == null) {
            if (other.uniTagList() != null) {
                return false;
            }
        } else if (!sub.uniTagList().equals(other.uniTagList())) {
            return false;
        }
        return true;
    }
}
