/*
 * 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.vpls.cli.completer;

import com.google.common.collect.ImmutableList;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Job;
import org.apache.felix.service.command.JobListener;
//import org.apache.karaf.shell.console.CommandSessionHolder;
//import org.apache.karaf.shell.console.completer.ArgumentCompleter;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.EncapsulationType;
import org.onosproject.vpls.VplsTest;
import org.onosproject.vpls.cli.VplsCommandEnum;

import java.io.InputStream;
import java.io.PrintStream;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static org.junit.Assert.*;

@Ignore("FIXME implement for new karaf CLI classes")
public class VplsCommandCompleterTest extends VplsTest {
    private static final String VPLS_CMD = "vpls";
    private TestCommandSession commandSession;

    @Before
    public void setup() {
        commandSession = new TestCommandSession();
        //CommandSessionHolder.setSession(commandSession);
    }

    /**
     * Test VPLS command completer.
     */
    @Test
    public void testCommandCompleter() {
        VplsCommandCompleter commandCompleter = new VplsCommandCompleter();
        List<String> choices = commandCompleter.choices();
        List<String> expected = VplsCommandEnum.toStringList();
        assertEquals(expected, choices);
    }

    /**
     * Test VPLS name completer.
     */
    @Test
    public void testNameCompleter() {
        VplsNameCompleter vplsNameCompleter = new VplsNameCompleter();
        vplsNameCompleter.vpls = new TestVpls();
        ((TestVpls) vplsNameCompleter.vpls).initSampleData();
        List<String> choices = vplsNameCompleter.choices();
        List<String> expected = ImmutableList.of(VPLS1, VPLS2);

        // Can not ensure the order, use contains all instead of equals
        assertEquals(choices.size(), expected.size());
        assertTrue(choices.containsAll(expected));
    }

    /**
     * Test VPLS option arguments completer.
     */
    @Test
    public void testOptArgCompleter() {
        VplsOptArgCompleter completer = new VplsOptArgCompleter();
        completer.vpls = new TestVpls();
        ((TestVpls) completer.vpls).initSampleData();
        completer.interfaceService = new TestInterfaceService();

        // Add interface to VPLS
        commandSession.updateArguments(VPLS_CMD, VplsCommandEnum.ADD_IFACE.toString(), VPLS1);

        List<String> choices = completer.choices();
        List<String> expected = ImmutableList.of(V300H1.name(),
                                                 V300H2.name(),
                                                 V400H1.name(),
                                                 VNONEH1.name(),
                                                 VNONEH2.name(),
                                                 VNONEH3.name());

        // Can not ensure the order, use contains all instead of equals
        assertEquals(choices.size(), expected.size());
        assertTrue(choices.containsAll(expected));

        // Removes interface from VPLS
        commandSession.updateArguments(VPLS_CMD, VplsCommandEnum.REMOVE_IFACE.toString(), VPLS1);
        choices = completer.choices();
        expected = completer.vpls.getVpls(VPLS1).interfaces().stream()
                .map(Interface::name)
                .collect(Collectors.toList());

        // Can not ensure the order, use contains all instead of equals
        assertEquals(choices.size(), expected.size());
        assertTrue(choices.containsAll(expected));

        // Sets encapsulation
        commandSession.updateArguments(VPLS_CMD, VplsCommandEnum.SET_ENCAP.toString(), VPLS1);
        choices = completer.choices();
        expected = Arrays.stream(EncapsulationType.values())
                .map(Enum::toString)
                .collect(Collectors.toList());

        // Can not ensure the order, use contains all instead of equals
        assertEquals(choices.size(), expected.size());
        assertTrue(choices.containsAll(expected));
    }

    /**
     * Test command session.
     */
    class TestCommandSession implements CommandSession {
        //ArgumentCompleter.ArgumentList argumentList;

        @Override
        public Path currentDir() {
            return null;
        }

        @Override
        public void currentDir(Path path) {

        }

        @Override
        public ClassLoader classLoader() {
            return null;
        }

        @Override
        public void classLoader(ClassLoader classLoader) {

        }

        @Override
        public List<Job> jobs() {
            return null;
        }

        @Override
        public Job foregroundJob() {
            return null;
        }

        @Override
        public void setJobListener(JobListener jobListener) {

        }

        public TestCommandSession() {
            String[] emptyStringArr = new String[0];
            //argumentList = new ArgumentCompleter.ArgumentList(emptyStringArr,
            //                                                  0,
            //                                                  0,
            //                                                  0);
        }

        /**
         * Updates argument list for the command session.
         *
         * @param args new arguments
         */
        public void updateArguments(String... args) {
            //argumentList = new ArgumentCompleter.ArgumentList(args,
            //                                                  0,
            //                                                  0,
            //                                                  0);
        }

        @Override
        public Object execute(CharSequence charSequence) throws Exception {
            return null;
        }

        @Override
        public void close() {

        }

        @Override
        public InputStream getKeyboard() {
            return null;
        }

        @Override
        public PrintStream getConsole() {
            return null;
        }

        @Override
        public Object get(String s) {
            return "";
            //return argumentList;
        }

        @Override
        public String put(String s, Object o) {
            return "";
        }

        @Override
        public CharSequence format(Object o, int i) {
            return null;
        }

        @Override
        public Object convert(Class<?> aClass, Object o) {
            return null;
        }
    }
}
