/*
 * Copyright 2016-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.yms.app.ysr;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network1.rev20151208.IetfNetwork1;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network1.rev20151208.IetfNetwork1OpParam;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network1.rev20151208.IetfNetwork1Service;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network2.rev20151208.IetfNetwork2Service;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangSchemaNode;

import java.io.IOException;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

/**
 * Unit test case for default schema registry.
 */
public class DefaultYangSchemaRegistryTest {

    private static final String SERVICE_NAME_1 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network1.rev20151208.IetfNetwork1Service";
    private static final String SCHEMA_NAME_1 = "ietf-network1";
    private static final String EVENT_NAME_1 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network1.rev20151208.ietfnetwork1.IetfNetwork1Event";
    private static final String INTERFACE_NAME_1 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network1.rev20151208.IetfNetwork1";
    private static final String OP_PARAM_NAME_1 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network1.rev20151208.IetfNetwork1OpParam";

    private static final String SERVICE_NAME_2 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network2.rev20151208.IetfNetwork2Service";
    private static final String SCHEMA_NAME_2 = "ietf-network2";
    private static final String EVENT_NAME_2 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network2.rev20151208.ietfnetwork2.IetfNetwork2Event";
    private static final String INTERFACE_NAME_2 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network2.rev20151208.IetfNetwork2";
    private static final String OP_PARAM_NAME_2 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network2.rev20151208.IetfNetwork2OpParam";

    private static final String SERVICE_NAME_3 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network3.rev20151208.IetfNetwork3Service";
    private static final String SCHEMA_NAME_3 = "ietf-network3";
    private static final String EVENT_NAME_3 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network3.rev20151208.ietfnetwork3.IetfNetwork3Event";
    private static final String INTERFACE_NAME_3 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network3.rev20151208.IetfNetwork3";
    private static final String OP_PARAM_NAME_3 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network3.rev20151208.IetfNetwork3OpParam";

    private static final String SCHEMA_NAME_4 = "ietf-network4";
    private static final String SERVICE_NAME_REV_14 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20141208.IetfNetwork4Service";
    private static final String EVENT_NAME_REV_14 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20141208.ietfnetwork4.IetfNetwork4Event";
    private static final String INTERFACE_NAME_REV_14 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20141208.IetfNetwork4";
    private static final String OP_PARAM_NAME_REV_14 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20141208.IetfNetwork4OpParam";

    private static final String SERVICE_NAME_REV_15 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20151208.IetfNetwork4Service";
    private static final String EVENT_NAME_REV_15 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20151208.ietfnetwork4.IetfNetwork4Event";
    private static final String INTERFACE_NAME_REV_15 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20151208.IetfNetwork4";
    private static final String OP_PARAM_NAME_REV_15 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20151208.IetfNetwork4OpParam";

    private static final String SERVICE_NAME_REV_16 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20161208.IetfNetwork4Service";

    private static final String EVENT_NAME_REV_16 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20161208.ietfnetwork4.IetfNetwork4Event";
    private static final String INTERFACE_NAME_REV_16 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20161208.IetfNetwork4";
    private static final String OP_PARAM_NAME_REV_16 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20161208.IetfNetwork4OpParam";

    private static final String SERVICE_NAME_REV_17 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20171208.IetfNetwork4Service";
    private static final String EVENT_NAME_REV_17 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20171208.ietfnetwork4.IetfNetwork4Event";
    private static final String INTERFACE_NAME_REV_17 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20171208.IetfNetwork4";
    private static final String OP_PARAM_NAME_REV_17 =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.rev20171208.IetfNetwork4OpParam";

    private static final String SERVICE_NAME_NO_REV =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.IetfNetwork4Service";
    private static final String EVENT_NAME_NO_REV =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.ietfnetwork4.IetfNetwork4Event";
    private static final String INTERFACE_NAME_NO_REV =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.IetfNetwork4";
    private static final String OP_PARAM_NAME_NO_REV =
            "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
                    ".network4.IetfNetwork4OpParam";

    private static final String DATE = "2014-00-08";
    private static final String SCHEMA_NAME_WITH_DATE =
            "ietf-network4@2014-00-08";

    private static final String UN_REG_SCHEMA_NAME = "ietf-routing";
    private static final String UN_REG_INTERFACE_NAME = "IetfRouting";
    private static final String UN_REG_OP_PARAM_NAME = "IetfRoutingOpParam";
    private static final String UN_REG_SERVICE_NAME = "IetfRoutingService";
    private static final String UN_REG_EVENT_NAME = "IetfRoutingEvent";

    private final TestYangSchemaNodeProvider testYangSchemaNodeProvider =
            new TestYangSchemaNodeProvider();
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    /**
     * Unit test case in which schema node should be present.
     *
     * @throws IOException when fails to do IO operation
     */
    @Test
    public void testForGetSchemaNode()
            throws IOException {

        testYangSchemaNodeProvider.processSchemaRegistry(null);

        DefaultYangSchemaRegistry registry =
                testYangSchemaNodeProvider.getDefaultYangSchemaRegistry();

        YangSchemaNode yangNode =
                registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_1);
        assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_1);
        assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_1);
        assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_1);
        assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));

        yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_1);
        assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));

        //As we have not registered an  application this object should be null.
        Object object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));
        testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_1);

        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_1);
        assertThat(true, is(yangNode == null));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_1);
        assertThat(true, is(yangNode == null));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_1);
        assertThat(true, is(yangNode == null));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_1);
        assertThat(true, is(yangNode == null));

        yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_1);
        assertThat(true, is(yangNode == null));

        //As we have not registered an  application this object should be null.
        object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));

        //With second service.
        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_2);
        assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_2);
        assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_2);
        assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_2);
        assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));

        yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_2);
        assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));

        //As we have not registered an  application this object should be null.
        object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));

        testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_2);

        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_2);
        assertThat(true, is(yangNode == null));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_2);
        assertThat(true, is(yangNode == null));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_2);
        assertThat(true, is(yangNode == null));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_2);
        assertThat(true, is(yangNode == null));

        yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_2);
        assertThat(true, is(yangNode == null));

        //As we have not registered an  application this object should be null.
        object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));

        //With third service.
        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_3);
        assertThat(true, is(SCHEMA_NAME_3.equals(yangNode.getName())));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_3);
        assertThat(true, is(SCHEMA_NAME_3.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_3);
        assertThat(true, is(SCHEMA_NAME_3.equals(yangNode.getName())));

        yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_3);
        assertThat(true, is(yangNode == null));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_3);
        assertThat(true, is(SCHEMA_NAME_3.equals(yangNode.getName())));

        //As we have not registered an  application this object should be null.
        object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));

        testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_3);

        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_3);
        assertThat(true, is(yangNode == null));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_3);
        assertThat(true, is(yangNode == null));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_3);
        assertThat(true, is(yangNode == null));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_3);
        assertThat(true, is(yangNode == null));

        yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_3);
        assertThat(true, is(yangNode == null));

        //As we have not registered an  application this object should be null.
        object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));
    }

    /**
     * Unit test case in which schema node should not be present.
     *
     * @throws IOException when fails to do IO operation
     */
    @Test
    public void testForDoNotGetSchemaNode()
            throws IOException {

        DefaultYangSchemaRegistry registry =
                testYangSchemaNodeProvider.getDefaultYangSchemaRegistry();

        // here all nodes should be null as we have not done any registration
        // for this application.
        YangSchemaNode yangNode =
                registry.getYangSchemaNodeUsingAppName(UN_REG_SERVICE_NAME);
        assertThat(true, is(yangNode == null));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(UN_REG_SCHEMA_NAME);
        assertThat(true, is(yangNode == null));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        UN_REG_INTERFACE_NAME);
        assertThat(true, is(yangNode == null));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        UN_REG_OP_PARAM_NAME);
        assertThat(true, is(yangNode == null));

        yangNode = registry.getRootYangSchemaNodeForNotification(
                UN_REG_EVENT_NAME);
        assertThat(true, is(yangNode == null));

        //As we have not registered an  application this object should be null.
        Object object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));

    }

    /**
     * Unit test case in which schema node should be present with multi
     * revisions.
     *
     * @throws IOException when fails to do IO operation
     */
    @Test
    public void testForGetSchemaNodeWhenNoRevision()
            throws IOException {

        testYangSchemaNodeProvider.processSchemaRegistry(null);
        DefaultYangSchemaRegistry registry =
                testYangSchemaNodeProvider.getDefaultYangSchemaRegistry();

        //Service with rev.
        YangSchemaNode yangNode =
                registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_15);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_REV_15);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_REV_15);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getRootYangSchemaNodeForNotification(
                EVENT_NAME_REV_15);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        //As we have not registered an  application this object should be null.
        Object object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));
        testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_15);

        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_15);
        assertThat(true, is(yangNode == null));

        //Here the yangNode should be the node which does not have revision.
        // asset should pass with false.
        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(((YangNode) yangNode).getRevision() != null));

        //Service no revision.
        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_NO_REV);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_NO_REV);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_NO_REV);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_NO_REV);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        //As we have not registered an  application this object should be null.
        object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));
        testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_NO_REV);

        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_NO_REV);
        assertThat(true, is(yangNode == null));

        //Here the yangNode should be the node which have different revision.
        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(((YangNode) yangNode).getRevision() != null));
    }

    /**
     * Unit test case in which schema node should be present with multi
     * revisions.
     *
     * @throws IOException when fails to do IO operation
     */
    @Test
    public void testForGetSchemaNodeWhenMultiRevision()
            throws IOException {

        testYangSchemaNodeProvider.processSchemaRegistry(null);
        DefaultYangSchemaRegistry registry =
                testYangSchemaNodeProvider.getDefaultYangSchemaRegistry();

        //Service with rev.
        YangSchemaNode yangNode =
                registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_15);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_REV_15);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_REV_15);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getRootYangSchemaNodeForNotification(
                EVENT_NAME_REV_15);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        //As we have not registered an  application this object should be null.
        Object object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));
        testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_15);

        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_15);
        assertThat(true, is(yangNode == null));

        //Here the yangNode should be the node which does not have revision.
        // asset should pass with false.
        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(((YangNode) yangNode).getRevision() != null));

        //Service with different revision.
        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_16);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_REV_16);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_REV_16);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_REV_16);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        //As we have not registered an  application this object should be null.
        object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));
        testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_16);

        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_16);
        assertThat(true, is(yangNode == null));

        //Here the yangNode should be the node which have different revision.
        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(((YangNode) yangNode).getRevision() != null));

        //Service with different revision.
        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_17);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_REV_17);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_REV_17);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getRootYangSchemaNodeForNotification(
                EVENT_NAME_REV_17);
        assertThat(true, is(yangNode == null));

        //As we have not registered an  application this object should be null.
        object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));
        testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_17);

        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_17);
        assertThat(true, is(yangNode == null));

        //Here the yangNode should be the node which have different revision.
        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(((YangNode) yangNode).getRevision() == null));

        //Service with different revision.
        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_14);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
                        INTERFACE_NAME_REV_14);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode =
                registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
                        OP_PARAM_NAME_REV_14);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        yangNode = registry.getRootYangSchemaNodeForNotification(
                EVENT_NAME_REV_14);
        assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));

        //As we have not registered an  application this object should be null.
        object = registry.getRegisteredApplication(yangNode);
        assertThat(true, is(object == null));
        testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_14);

        yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_14);
        assertThat(true, is(yangNode == null));

        //Here the yangNode should be the node which does not have revision.
        // asset should pass with false.
        yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
        assertThat(true, is(yangNode != null));

    }

    /**
     * Unit test case should generate exceptions.
     */
    @Test
    public void testRegistration() {
        thrown.expect(RuntimeException.class);
        testYangSchemaNodeProvider.processSchemaRegistry(null);
        testYangSchemaNodeProvider.processRegistrationOfApp();
    }

    /**
     * Unit test case should not generate any exceptions and should
     * return specific revision node.
     */
    @Test
    public void testGetWithSpecificRevision() {
        testYangSchemaNodeProvider.processSchemaRegistry(null);
        YangSchemaNode schemaNode = testYangSchemaNodeProvider
                .getDefaultYangSchemaRegistry()
                .getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_WITH_DATE);

        assertThat(true, is(schemaNode.getName().equals(SCHEMA_NAME_4)));
        String date = testYangSchemaNodeProvider
                .getDefaultYangSchemaRegistry()
                .getDateInStringFormat(schemaNode);
        assertThat(true, is(date.equals(DATE)));
    }

    /**
     * Unit test case should not generate any exceptions
     * verify notification should be checked for registration.
     */
    @Test
    public void testNotification() {
        testYangSchemaNodeProvider.processSchemaRegistry(null);
        boolean isRegWithNotification =
                testYangSchemaNodeProvider.getDefaultYangSchemaRegistry()
                        .verifyNotificationObject(IetfNetwork1Service.class);
        assertThat(true, is(isRegWithNotification));
        isRegWithNotification = testYangSchemaNodeProvider
                .getDefaultYangSchemaRegistry()
                .verifyNotificationObject(IetfNetwork1.class);
        assertThat(false, is(isRegWithNotification));
        isRegWithNotification = testYangSchemaNodeProvider
                .getDefaultYangSchemaRegistry()
                .verifyNotificationObject(IetfNetwork1OpParam.class);
        assertThat(false, is(isRegWithNotification));
    }

    /**
     * Unit test case should not generate any exceptions.
     */
    @Test
    public void testNotificationRegistrationInYnh() {
        testYangSchemaNodeProvider.processSchemaRegistry(null);
        testYangSchemaNodeProvider.getDefaultYangSchemaRegistry()
                .verifyNotificationObject(IetfNetwork1Service.class);
        testYangSchemaNodeProvider.getDefaultYangSchemaRegistry()
                .verifyNotificationObject(IetfNetwork1.class);
        testYangSchemaNodeProvider.getDefaultYangSchemaRegistry()
                .verifyNotificationObject(IetfNetwork1OpParam.class);

        boolean isRegWithNotification = testYangSchemaNodeProvider
                .getDefaultYangSchemaRegistry()
                .verifyNotificationObject(IetfNetwork2Service.class);

        //Register should work.
        assertThat(true, is(isRegWithNotification));
        isRegWithNotification = testYangSchemaNodeProvider
                .getDefaultYangSchemaRegistry()
                .verifyNotificationObject(IetfNetwork2Service.class);

        //Re register should not happen
        assertThat(false, is(isRegWithNotification));
    }

}


