/*
 * Copyright 2016 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.codec.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.VlanId;
import org.onosproject.codec.JsonCodec;
import org.onosproject.core.CoreService;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flowobjective.DefaultFilteringObjective;
import org.onosproject.net.flowobjective.FilteringObjective;

import java.io.IOException;
import java.io.InputStream;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.onosproject.codec.impl.FilteringObjectiveJsonMatcher.matchesFilteringObjective;
import static org.onosproject.net.NetTestTools.APP_ID;

/**
 * Unit tests for FilteringObjective Codec.
 */
public class FilteringObjectiveCodecTest {

    MockCodecContext context;
    JsonCodec<FilteringObjective> filteringObjectiveCodec;
    final CoreService mockCoreService = createMock(CoreService.class);

    /**
     * Sets up for each test.
     * Creates a context and fetches the FilteringObjective codec.
     */
    @Before
    public void setUp() {
        context = new MockCodecContext();
        filteringObjectiveCodec = context.codec(FilteringObjective.class);
        assertThat(filteringObjectiveCodec, notNullValue());

        expect(mockCoreService.registerApplication(FilteringObjectiveCodec.REST_APP_ID))
                .andReturn(APP_ID).anyTimes();
        replay(mockCoreService);
        context.registerService(CoreService.class, mockCoreService);
    }

    /**
     * Tests encoding of a FilteringObjective object.
     */
    @Test
    public void testFilteringObjectiveEncode() {

        Criterion condition1 = Criteria.matchVlanId(VlanId.ANY);
        Criterion condition2 = Criteria.matchEthType((short) 0x8844);

        FilteringObjective filteringObj = DefaultFilteringObjective.builder()
                .makePermanent()
                .permit()
                .fromApp(APP_ID)
                .withPriority(60)
                .addCondition(condition1)
                .addCondition(condition2)
                .add();

        // TODO: need to add test case for TrafficTreatment (META in filteringObj)

        ObjectNode filteringObjJson = filteringObjectiveCodec.encode(filteringObj, context);
        assertThat(filteringObjJson, matchesFilteringObjective(filteringObj));
    }

    /**
     * Test decoding of a FilteringObjective object.
     */
    @Test
    public void testFilteringObjectiveDecode() throws IOException {
        FilteringObjective filteringObjective = getFilteringObjective("FilteringObjective.json");

        assertThat(filteringObjective.type(), is(FilteringObjective.Type.PERMIT));
        assertThat(filteringObjective.priority(), is(60));
        assertThat(filteringObjective.timeout(), is(1));
        assertThat(filteringObjective.op(), is(FilteringObjective.Operation.ADD));
        assertThat(filteringObjective.permanent(), is(false));
    }

    /**
     * Reads in a filteringObjective from the given resource and decodes it.
     *
     * @param resourceName resource to use to read the JSON for the rule
     * @return decoded filteringObjective
     * @throws IOException if processing the resource fails
     */
    private FilteringObjective getFilteringObjective(String resourceName) throws IOException {
        InputStream jsonStream = FilteringObjectiveCodecTest.class.getResourceAsStream(resourceName);
        JsonNode json = context.mapper().readTree(jsonStream);
        assertThat(json, notNullValue());
        FilteringObjective filteringObjective = filteringObjectiveCodec.decode((ObjectNode) json, context);
        assertThat(filteringObjective, notNullValue());
        return filteringObjective;
    }
}
