/*
 * 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.
 */
package org.opencord.aaa.impl;

import com.google.common.base.Charsets;
import org.onlab.packet.BasePacket;
import org.onlab.packet.EAP;
import org.onlab.packet.EAPOL;
import org.onlab.packet.EthType;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onlab.packet.RADIUS;
import org.onlab.packet.RADIUSAttribute;
import org.onlab.packet.VlanId;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.cfg.ConfigProperty;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Element;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.DefaultPacketContext;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketServiceAdapter;
import org.opencord.sadis.BandwidthProfileInformation;
import org.opencord.sadis.BaseInformationService;
import org.opencord.sadis.SadisService;
import org.opencord.sadis.SubscriberAndDeviceInformation;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.ComponentInstance;

import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.onosproject.net.NetTestTools.connectPoint;

/**
 * Common methods for AAA app testing.
 */
public class AaaTestBase {

    MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
    MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a");

    // Our session id will be the device ID ("of:1") with the port ("1") concatenated
    static final String SESSION_ID = "of:11";

    List<BasePacket> savedPackets = new LinkedList<>();
    PacketProcessor packetProcessor;

    /**
     * Saves the given packet onto the saved packets list.
     *
     * @param packet packet to save
     */
    void savePacket(BasePacket packet) {
        savedPackets.add(packet);
    }

    /**
     * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
     */
    class MockPacketService extends PacketServiceAdapter {

        @Override
        public void addProcessor(PacketProcessor processor, int priority) {
            packetProcessor = processor;
        }

        @Override
        public void emit(OutboundPacket packet) {
            try {
                Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
                                                                   0, packet.data().array().length);
                savePacket(eth);
            } catch (Exception e) {
                fail(e.getMessage());
            }
        }
    }
    class MockComponentContext implements ComponentContext {

                @Override
                public Dictionary<String, Object> getProperties() {
                        Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
                        cfgDict.put("statisticsGenerationEvent", 20);
                        return cfgDict;
                }

                @Override
                public Object locateService(String name) {
                        // TODO Auto-generated method stub
                        return null;
                }

                @Override
                public Object locateService(String name, ServiceReference reference) {
                        // TODO Auto-generated method stub
                        return null;
                }

                @Override
                public Object[] locateServices(String name) {
                        // TODO Auto-generated method stub
                        return null;
                }

                @Override
                public BundleContext getBundleContext() {
                        // TODO Auto-generated method stub
                        return null;
                }

                @Override
                public Bundle getUsingBundle() {
                        // TODO Auto-generated method stub
                        return null;
                }

                @Override
                public ComponentInstance getComponentInstance() {
                        // TODO Auto-generated method stub
                        return null;
                }

                @Override
                public void enableComponent(String name) {
                        // TODO Auto-generated method stub
                }

                @Override
                public void disableComponent(String name) {
                       // TODO Auto-generated method stub
                }

                @Override
                public ServiceReference getServiceReference() {
                       // TODO Auto-generated method stub
                       return null;
                }
    }

    /**
     * Mocks the DeviceService.
     */
    final class TestDeviceService extends DeviceServiceAdapter {
        @Override
        public Port getPort(ConnectPoint cp) {
            return new MockPort();
        }
    }
    private class  MockPort implements Port {

        @Override
        public boolean isEnabled() {
            return true;
        }
        public long portSpeed() {
            return 1000;
        }
        public Element element() {
            return null;
        }
        public PortNumber number() {
            return null;
        }
        public Annotations annotations() {
            return new MockAnnotations();
        }
        public Type type() {
            return Port.Type.FIBER;
        }

        private class MockAnnotations implements Annotations {

            @Override
            public String value(String val) {
                return "PON 1/1";
            }
            public Set<String> keys() {
                return null;
            }
        }
    }

    private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {

        MockSubscriberAndDeviceInformation(String id, VlanId ctag,
                                           VlanId stag, String nasPortId,
                                           String circuitId, MacAddress hardId,
                                           Ip4Address ipAddress) {
            this.setCTag(ctag);
            this.setHardwareIdentifier(hardId);
            this.setId(id);
            this.setIPAddress(ipAddress);
            this.setSTag(stag);
            this.setNasPortId(nasPortId);
            this.setCircuitId(circuitId);
        }
    }

    final class MockSadisService implements SadisService {

        @Override
        public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
            return new MockSubService();
        }

        @Override
        public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
            return null;
        }
    }

    final class MockCfgService implements ComponentConfigService {
        @Override
        public Set<String> getComponentNames() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void registerProperties(Class<?> componentClass) {
            // TODO Auto-generated method stub
        }

        @Override
        public void unregisterProperties(Class<?> componentClass, boolean clear) {
            // TODO Auto-generated method stub
        }

        @Override
        public Set<ConfigProperty> getProperties(String componentName) {
           return null;
        }

        @Override
        public void setProperty(String componentName, String name, String value) {
            // TODO Auto-generated method stub
        }

        @Override
        public void preSetProperty(String componentName, String name, String value) {
            // TODO Auto-generated method stub
        }

        @Override
        public void preSetProperty(String componentName, String name, String value, boolean override) {
            // TODO Auto-generated method stub
        }

        @Override
        public void unsetProperty(String componentName, String name) {
            // TODO Auto-generated method stub
        }

        @Override
        public ConfigProperty getProperty(String componentName, String attribute) {
           return null;
        }

}

    final class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
        private final VlanId clientCtag = VlanId.vlanId((short) 999);
        private final VlanId clientStag = VlanId.vlanId((short) 111);
        private final String clientNasPortId = "PON 1/1";
        private final String clientCircuitId = "CIR-PON 1/1";

        MockSubscriberAndDeviceInformation sub =
                new MockSubscriberAndDeviceInformation(clientNasPortId, clientCtag,
                        clientStag, clientNasPortId, clientCircuitId, null, null);
        @Override
        public SubscriberAndDeviceInformation get(String id) {

                return  sub;

        }

        @Override
        public void invalidateAll() {}
        public void invalidateId(String id) {}
        public SubscriberAndDeviceInformation getfromCache(String id) {
            return null;
        }
    }
    /**
     * Mocks the DefaultPacketContext.
     */
    final class TestPacketContext extends DefaultPacketContext {

        TestPacketContext(long time, InboundPacket inPkt,
                                  OutboundPacket outPkt, boolean block) {
            super(time, inPkt, outPkt, block);
        }

        @Override
        public void send() {
            // We don't send anything out.
        }
    }

    /**
     * Sends an Ethernet packet to the process method of the Packet Processor.
     *
     * @param reply Ethernet packet
     */
    void sendPacket(Ethernet reply) {
        final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
        InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
                                                          reply,
                                                          byteBuffer);

        PacketContext context = new TestPacketContext(127L, inPacket, null, false);
        packetProcessor.process(context);
    }

    /**
     * Constructs an Ethernet packet containing identification payload.
     *
     * @return Ethernet packet
     */
    Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine,
                                                       byte type,
                                                       byte id,
                                                       Ethernet radiusChallenge)
            throws Exception {
        Ethernet eth = new Ethernet();
        eth.setDestinationMACAddress(clientMac.toBytes());
        eth.setSourceMACAddress(serverMac.toBytes());
        eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
        eth.setVlanID((short) 2);

        String username = "testuser";
        byte[] data = username.getBytes();


        if (type == EAP.ATTR_MD5) {
            String password = "testpassword";
            EAPOL eapol = (EAPOL) radiusChallenge.getPayload();
            EAP eap = (EAP) eapol.getPayload();

            byte[] identifier = new byte[password.length() + eap.getData().length];

            identifier[0] = stateMachine.challengeIdentifier();
            System.arraycopy(password.getBytes(), 0, identifier, 1, password.length());
            System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16);

            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hash = md.digest(identifier);
            data = new byte[17];
            data[0] = (byte) 16;
            System.arraycopy(hash, 0, data, 1, 16);
        }
        EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type,
                          data);
        eap.setIdentifier(id);

        // eapol header
        EAPOL eapol = new EAPOL();
        eapol.setEapolType(EAPOL.EAPOL_PACKET);
        eapol.setPacketLength(eap.getLength());

        // eap part
        eapol.setPayload(eap);

        eth.setPayload(eapol);
        eth.setPad(true);
        return eth;
    }

    /**
     * Constructs an Ethernet packet containing a EAPOL_START Payload.
     *
     * @return Ethernet packet
     */
    Ethernet constructSupplicantStartPacket() {
        Ethernet eth = new Ethernet();
        eth.setDestinationMACAddress(clientMac.toBytes());
        eth.setSourceMACAddress(serverMac.toBytes());
        eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
        eth.setVlanID((short) 2);

        EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 3, EAPOL.EAPOL_START, null);

        // eapol header
        EAPOL eapol = new EAPOL();
        eapol.setEapolType(EAPOL.EAPOL_START);
        eapol.setPacketLength(eap.getLength());

        // eap part
        eapol.setPayload(eap);

        eth.setPayload(eapol);
        eth.setPad(true);
        return eth;
    }

    /**
     * Checks the contents of a RADIUS packet being sent to the RADIUS server.
     *
     * @param radiusPacket packet to check
     * @param code expected code
     */
    void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) {

        assertThat(radiusPacket.getSourceMAC(),
                   is(MacAddress.valueOf(aaaManager.nasMacAddress)));
        assertThat(radiusPacket.getDestinationMAC(), is(serverMac));

        assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
        EAPOL eapol = (EAPOL) radiusPacket.getPayload();
        assertThat(eapol, notNullValue());

        assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
        assertThat(eapol.getPayload(), instanceOf(EAP.class));
        EAP eap = (EAP) eapol.getPayload();
        assertThat(eap, notNullValue());

        assertThat(eap.getCode(), is(code));
    }

    /**
     * Constructs an Ethernet packet containing a EAPOL_LOGOFF Payload.
     *
     * @return Ethernet packet
     */
    Ethernet constructSupplicantLogoffPacket() {
        Ethernet eth = new Ethernet();
        eth.setDestinationMACAddress(clientMac.toBytes());
        eth.setSourceMACAddress(serverMac.toBytes());
        eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
        eth.setVlanID((short) 2);

        EAP eap = new EAP(EAPOL.EAPOL_LOGOFF, (byte) 2, EAPOL.EAPOL_LOGOFF, null);

        // eapol header
        EAPOL eapol = new EAPOL();
        eapol.setEapolType(EAPOL.EAPOL_LOGOFF);
        eapol.setPacketLength(eap.getLength());

        // eap part
        eapol.setPayload(eap);

        eth.setPayload(eapol);
        eth.setPad(true);
        return eth;
    }

    /**
     * Constructs an Ethernet packet containing a RADIUS challenge
     * packet.
     *
     * @param challengeCode code to use in challenge packet
     * @param challengeType type to use in challenge packet
     * @return Ethernet packet
     */
    RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType,
            byte identifier, byte[] messageAuth) {

        String challenge = "12345678901234567";

        EAP eap = new EAP(challengeType, (byte) 4, challengeType,
                challenge.getBytes(Charsets.US_ASCII));
        //eap.setIdentifier((byte) 4);
        eap.setIdentifier(identifier);

        RADIUS radius = new RADIUS();
        radius.setCode(challengeCode);
        //radius.setIdentifier((byte) 4);
        radius.setIdentifier(identifier);
        radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
                challenge.getBytes(Charsets.US_ASCII));

        radius.setPayload(eap);
        radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE, eap.serialize());
        radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, messageAuth);
        return radius;
    }
}
