/*
 * 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.onosproject.cfm.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.packet.VlanId;
import org.onlab.rest.BaseResource;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.codec.CodecService;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMep;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;

import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Duration;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Optional;

import static junit.framework.TestCase.fail;
import static org.easymock.EasyMock.*;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

public class MepWebResourceTest extends CfmResourceTest {
    private final CfmMepService mepService = createMock(CfmMepService.class);
    private final CfmMdService mdService = createMock(CfmMdService.class);

    private static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
    private static final MaIdShort MANAME1 = MaIdCharStr.asMaId("ma-1-1");
    private static final MepId MEPID1 = MepId.valueOf((short) 1);

    private MepEntry mepEntry1 = null;

    @Before
    public void setUpTest() throws CfmConfigException {
        CfmCodecContext context = new CfmCodecContext();
        ServiceDirectory testDirectory = new TestServiceDirectory()
                .add(CfmMepService.class, mepService)
                .add(CfmMdService.class, mdService)
                .add(CodecService.class, context.codecManager());
        BaseResource.setServiceDirectory(testDirectory);

        mepEntry1 = DefaultMepEntry.builder(
                    MEPID1,
                    DeviceId.deviceId("netconf:1.2.3.4:830"),
                    PortNumber.portNumber(1),
                    Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
                .buildEntry();

    }

    @Test
    public void testGetAllMepsForMaEmpty() throws CfmConfigException {

        expect(mepService.getAllMeps(MDNAME1, MANAME1)).andReturn(null).anyTimes();
        replay(mepService);

        final WebTarget wt = target();
        final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep").request().get(String.class);
        assertThat(response, is("{\"meps\":[[]]}"));
    }

    @Test
    public void testGetAllMepsForMa1Mep() throws CfmConfigException {
        Collection<MepEntry> meps = new ArrayList<>();
        meps.add(mepEntry1);

        expect(mepService.getAllMeps(MDNAME1, MANAME1)).andReturn(meps).anyTimes();
        replay(mepService);

        final WebTarget wt = target();
        final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep").request().get(String.class);

        assertThat(response, is("{\"meps\":" +
                "[[{" +
                "\"mepId\":" + MEPID1.value() + "," +
                "\"deviceId\":\"netconf:1.2.3.4:830\"," +
                "\"port\":1," +
                "\"direction\":\"UP_MEP\"," +
                "\"mdName\":\"" + MDNAME1.mdName() + "\"," +
                "\"maName\":\"" + MANAME1.maName() + "\"," +
                "\"administrative-state\":false," +
                "\"cci-enabled\":false," +
                "\"remoteMeps\":[]}]]}"));
    }

    @Test
    public void testGetMepValid() throws CfmConfigException {

        expect(mepService.getMep(MDNAME1, MANAME1, MepId.valueOf((short) 1)))
                .andReturn(mepEntry1).anyTimes();
        replay(mepService);

        final WebTarget wt = target();
        final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep/" + MEPID1.value()).request().get(String.class);

        assertThat(response, is("{\"mep\":" +
                "{" +
                "\"mepId\":" + MEPID1.value() + "," +
                "\"deviceId\":\"netconf:1.2.3.4:830\"," +
                "\"port\":1," +
                "\"direction\":\"UP_MEP\"," +
                "\"mdName\":\"" + MDNAME1.mdName() + "\"," +
                "\"maName\":\"" + MANAME1.maName() + "\"," +
                "\"administrative-state\":false," +
                "\"cci-enabled\":false," +
                "\"remoteMeps\":[]}}"));
    }

    @Test
    public void testGetMepNotFound() throws CfmConfigException, IOException {

        expect(mepService.getMep(MDNAME1, MANAME1, MepId.valueOf((short) 2)))
                .andReturn(null).anyTimes();
        replay(mepService);

        final WebTarget wt = target();

        try {
            final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                    MANAME1.maName() + "/mep/" + 2).request().get(String.class);
            fail("Expected exception to be thrown");
        } catch (InternalServerErrorException e) {
            ByteArrayInputStream is = (ByteArrayInputStream) e.getResponse().getEntity();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line = null;
            StringBuffer sb = new StringBuffer();
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            assertEquals("{ \"failure\":\"MEP md-1/ma-1-1/2 not found\" }", sb.toString());
        }
    }

    @Test
    public void testDeleteMepValid() throws CfmConfigException {

        expect(mepService.deleteMep(MDNAME1, MANAME1, MepId.valueOf((short) 1)))
                .andReturn(true).anyTimes();
        replay(mepService);

        final WebTarget wt = target();
        final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep/" + MEPID1.value()).request().delete();

        assertEquals("Expecting 200", 200, response.getStatus());
    }

    @Test
    public void testDeleteMepNotFound() throws CfmConfigException {

        expect(mepService.deleteMep(MDNAME1, MANAME1, MepId.valueOf((short) 2)))
                .andReturn(false).anyTimes();
        replay(mepService);

        final WebTarget wt = target();
        final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep/2").request().delete();

        assertEquals("Expecting 304", 304, response.getStatus());
    }

    @Test
    public void testCreateMep() throws CfmConfigException, IOException {
        MepId mepId2 = MepId.valueOf((short) 2);
        Mep mep2 = DefaultMep.builder(
                mepId2,
                DeviceId.deviceId("netconf:2.2.3.4:830"),
                PortNumber.portNumber(2),
                Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build();

        MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
                .builder(MANAME1, MDNAME1.getNameLength()).build();

        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
                                .andReturn(Optional.ofNullable(ma1)).anyTimes();
        replay(mdService);
        expect(mepService.createMep(MDNAME1, MANAME1, mep2))
                                .andReturn(true).anyTimes();
        replay(mepService);

        ObjectMapper mapper = new ObjectMapper();
        CfmCodecContext context = new CfmCodecContext();
        ObjectNode node = mapper.createObjectNode();
        node.set("mep", context.codec(Mep.class).encode(mep2, context));

        final WebTarget wt = target();
        final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep")
                .request()
                .post(Entity.json(node.toString()));

        assertEquals("Expecting 201", 201, response.getStatus());
    }

    @Test
    public void testCreateMepAlreadyExists() throws CfmConfigException, IOException {
        MepId mepId3 = MepId.valueOf((short) 3);
        Mep mep3 = DefaultMep.builder(
                    mepId3,
                    DeviceId.deviceId("netconf:3.2.3.4:830"),
                    PortNumber.portNumber(3),
                    Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
                .cciEnabled(true)
                .ccmLtmPriority(Mep.Priority.PRIO3)
                .administrativeState(false)
                .primaryVid(VlanId.vlanId((short) 3))
                .defectAbsentTime(Duration.ofMinutes(2))
                .defectPresentTime(Duration.ofMinutes(3))
                .fngAddress(Mep.FngAddress.notSpecified())
                .lowestFaultPriorityDefect(Mep.LowestFaultDefect.ALL_DEFECTS)
                .build();

        MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
                .builder(MANAME1, MDNAME1.getNameLength()).build();

        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
                .andReturn(Optional.ofNullable(ma1)).anyTimes();
        replay(mdService);
        expect(mepService.createMep(MDNAME1, MANAME1, mep3))
                .andReturn(false).anyTimes();
        replay(mepService);

        ObjectMapper mapper = new ObjectMapper();
        CfmCodecContext context = new CfmCodecContext();
        ObjectNode node = mapper.createObjectNode();
        node.set("mep", context.codec(Mep.class).encode(mep3, context));

        final WebTarget wt = target();
        final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep")
                .request()
                .post(Entity.json(node.toString()));

        assertEquals("Expecting 304", 304, response.getStatus());
    }

    @Test
    public void testTransmitLoopback() throws CfmConfigException {
        MepLbCreate mepLbCreate1 = DefaultMepLbCreate
                .builder(MEPID1)
                .numberMessages(20)
                .dataTlvHex("AA:BB:CC:DD")
                .vlanDropEligible(true)
                .build();

        MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
                .builder(MANAME1, MDNAME1.getNameLength()).build();
        MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
                .addToMaList(ma1).build();
        expect(mdService.getMaintenanceDomain(MDNAME1))
                        .andReturn(Optional.ofNullable(md1)).anyTimes();
        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
                        .andReturn(Optional.ofNullable(ma1)).anyTimes();
        replay(mdService);

        ObjectMapper mapper = new ObjectMapper();
        CfmCodecContext context = new CfmCodecContext();
        ObjectNode node = mapper.createObjectNode();
        node.set("loopback", context.codec(MepLbCreate.class).encode(mepLbCreate1, context));

        final WebTarget wt = target();
        final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep/" + MEPID1.value() + "/transmit-loopback")
                .request()
                .put(Entity.json(node.toString()));

        assertEquals("Expecting 202", 202, response.getStatus());
    }

    @Test
    public void testAbortLoopback() throws CfmConfigException {

        MepLbCreate mepLbCreate1 = DefaultMepLbCreate.builder(MEPID1).build();

        MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
                .builder(MANAME1, MDNAME1.getNameLength()).build();
        MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
                .addToMaList(ma1).build();
        expect(mdService.getMaintenanceDomain(MDNAME1))
                .andReturn(Optional.ofNullable(md1)).anyTimes();
        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
                .andReturn(Optional.ofNullable(ma1)).anyTimes();
        replay(mdService);

        final WebTarget wt = target();
        final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep/" + MEPID1.value() + "/abort-loopback")
                .request()
                .put(Entity.json(""));

        assertEquals("Expecting 202", 202, response.getStatus());

    }

    @Test
    public void testTransmitLinktrace() throws CfmConfigException {
        MepLtCreate mepLtCreate1 = DefaultMepLtCreate
                .builder(MEPID1)
                .defaultTtl((short) 20)
                .transmitLtmFlags(BitSet.valueOf(new byte[]{1}))
                .build();

        MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
                .builder(MANAME1, MDNAME1.getNameLength()).build();
        MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
                .addToMaList(ma1).build();
        expect(mdService.getMaintenanceDomain(MDNAME1))
                .andReturn(Optional.ofNullable(md1)).anyTimes();
        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
                .andReturn(Optional.ofNullable(ma1)).anyTimes();
        replay(mdService);

        ObjectMapper mapper = new ObjectMapper();
        CfmCodecContext context = new CfmCodecContext();
        ObjectNode node = mapper.createObjectNode();
        node.set("linktrace", context.codec(MepLtCreate.class).encode(mepLtCreate1, context));

        final WebTarget wt = target();
        final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
                MANAME1.maName() + "/mep/" + MEPID1.value() + "/transmit-linktrace")
                .request()
                .put(Entity.json(node.toString()));

        assertEquals("Expecting 202", 202, response.getStatus());
    }
}
