/*
 * Copyright 2015-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.
 *
 * Originally created by Pengfei Lu, Network and Cloud Computing Laboratory, Dalian University of Technology, China
 * Advisers: Keqiu Li and Heng Qi
 * This work is supported by the State Key Program of National Natural Science of China(Grant No. 61432002)
 * and Prospective Research Project on Future Networks in Jiangsu Future Networks Innovation Institute.
 */

package org.onosproject.acl;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
import org.onosproject.core.IdGenerator;

import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

import static org.easymock.EasyMock.*;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertThat;

/**
 * Test class for ACL application REST resource.
 */
public class AclWebResourceTest extends JerseyTest {

    final AclService mockAclService = createMock(AclService.class);
    final AclStore mockAclStore = createMock(AclStore.class);
    final List<AclRule> rules = new ArrayList<>();

    /**
     * Constructs a control metrics collector resource test instance.
     */
    public AclWebResourceTest() {
        super(ResourceConfig.forApplicationClass(AclWebApplication.class));
    }

    @Before
    public void setUpMock() {
        expect(mockAclService.getAclRules()).andReturn(rules).anyTimes();
        ServiceDirectory testDirectory = new TestServiceDirectory()
                .add(AclService.class, mockAclService)
                .add(AclStore.class, mockAclStore);
        BaseResource.setServiceDirectory(testDirectory);

        AclRule.idGenerator = new MockIdGenerator();
    }

    @After
    public void tearDown() {
        verify(mockAclService);
    }

    /**
     * Mock id generator for testing.
     */
    private class MockIdGenerator implements IdGenerator {
        private AtomicLong nextId = new AtomicLong(0);

        @Override
        public long getNewId() {
            return nextId.getAndIncrement();
        }
    }

    @Test
    @Ignore("FIXME: This needs to get reworked")
    public void addRule() throws IOException {
        WebTarget wt = target();
        String response;
        String json;

        replay(mockAclService);

        // FIXME: following code snippet requires refactoring by extracting
        // json string as a separated file

        // input a invalid JSON string that contains neither nw_src and nw_dst
        json = "{\"ipProto\":\"TCP\",\"dstTpPort\":\"80\"}";
        response = wt.request().post(Entity.json(json), String.class);
        assertThat(response, containsString("Failed! Either srcIp or dstIp must be assigned."));

        // input a invalid JSON string that doesn't contain CIDR mask bits
        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
        response = wt.request().post(Entity.json(json), String.class);
        assertThat(response, containsString("Malformed IPv4 prefix string: 10.0.0.1. " +
                                                    "Address must take form \"x.x.x.x/y\""));

        // input a invalid JSON string that contains a invalid IP address
        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.256/32\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
        response = wt.request().post(Entity.json(json), String.class);
        assertThat(response, containsString("Invalid IP address string: 10.0.0.256"));

        // input a invalid JSON string that contains a invalid IP address
        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.01/32\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
        response = wt.request().post(Entity.json(json), String.class);
        assertThat(response, containsString("Invalid IP address string: 10.0.01"));

        // input a invalid JSON string that contains a invalid CIDR mask bits
        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1/a\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
        response = wt.request().post(Entity.json(json), String.class);
        assertThat(response, containsString("Failed! For input string: \"a\""));

        // input a invalid JSON string that contains a invalid CIDR mask bits
        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1/33\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
        response = wt.request().post(Entity.json(json), String.class);
        assertThat(response, containsString("Invalid prefix length 33. The value must be in the interval [0, 32]"));

        // input a invalid JSON string that contains a invalid ipProto value
        json = "{\"ipProto\":\"ARP\",\"srcIp\":\"10.0.0.1/32\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
        response = wt.request().post(Entity.json(json), String.class);
        assertThat(response, containsString("ipProto must be assigned to TCP, UDP, or ICMP."));

        // input a invalid JSON string that contains a invalid dstTpPort value
        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1/32\",\"dstTpPort\":\"a\",\"action\":\"DENY\"}";
        response = wt.request().post(Entity.json(json), String.class);
        assertThat(response, containsString("dstTpPort must be assigned to a numerical value."));

        // input a invalid JSON string that contains a invalid action value
        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1/32\",\"dstTpPort\":\"80\",\"action\":\"PERMIT\"}";
        response = wt.request().post(Entity.json(json), String.class);
        assertThat(response, containsString("action must be assigned to ALLOW or DENY."));
    }
}
