/*
 * Copyright 2016-present 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.yangutils.utils.io.impl;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.List;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertThat;
import static org.onosproject.yangutils.utils.io.impl.YangFileScanner.getJavaFiles;
import static org.onosproject.yangutils.utils.io.impl.YangFileScanner.getYangFiles;

import static java.io.File.separator;

/**
 * Test the file scanner service.
 */
public final class YangFileScannerTest {

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    String baseDir = "target/UnitTestCase";

    /**
     * A private constructor is tested.
     *
     * @throws SecurityException         if any security violation is observed
     * @throws NoSuchMethodException     if when the method is not found
     * @throws IllegalArgumentException  if there is illegal argument found
     * @throws InstantiationException    if instantiation is provoked for the private constructor
     * @throws IllegalAccessException    if instance is provoked or a method is provoked
     * @throws InvocationTargetException when an exception occurs by the method or constructor
     */
    @Test
    public void callPrivateConstructors() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
            InstantiationException, IllegalAccessException, InvocationTargetException {

        Class<?>[] classesToConstruct = {YangFileScanner.class };
        for (Class<?> clazz : classesToConstruct) {
            Constructor<?> constructor = clazz.getDeclaredConstructor();
            constructor.setAccessible(true);
            assertThat(null, not(constructor.newInstance()));
        }
    }

    /**
     * This test case checks for a .java file inside the specified dir.
     *
     * @throws IOException when fails to do IO operations
     */
    @Test
    public void checkJavaFileInsideDirTest() throws IOException {

        String dir = baseDir + separator + "scanner2";
        File path = createDirectory(dir);
        createFile(path, "testScanner.java");
        List<String> dirContents = getJavaFiles(path.toString());
        List<String> expectedContents = new LinkedList<>();
        expectedContents.add(path.getCanonicalPath() + separator + "testScanner.java");
        assertThat(true, is(dirContents.equals(expectedContents)));
    }

    /**
     * Method used for creating multiple directories inside the target file.
     *
     * @param path where directories should be created
     * @return the directory path that is created
     */
    private File createDirectory(String path) {

        File myDir = new File(path);
        myDir.mkdirs();
        return myDir;
    }

    /**
     * Method used for creating file inside the specified directory.
     *
     * @param myDir    the path where file has to be created inside
     * @param fileName the name of the file to be created
     */
    private void createFile(File myDir, String fileName) throws IOException {

        File file = null;
        file = new File(myDir + separator + fileName);
        file.createNewFile();
    }

    /**
     * This testcase checks for a java file inside an empty directory.
     *
     * @throws IOException when fails to do IO operations
     */
    @Test
    public void emptyDirJavaScannerTest() throws IOException {

        String emptyDir = baseDir + separator + "scanner1";
        File path = createDirectory(emptyDir);
        List<String> emptyDirContents = getJavaFiles(path.toString());
        List<String> expectedContents = new LinkedList<>();
        assertThat(true, is(emptyDirContents.equals(expectedContents)));
    }

    /**
     * This testcase checks for a yang file inside an empty directory.
     *
     * @throws IOException when fails to do IO operations
     */
    @Test
    public void emptyDirYangScannerTest() throws IOException {

        String emptyYangDir = baseDir + separator + "scanner1";
        File path = createDirectory(emptyYangDir);
        List<String> emptyDirContents = getYangFiles(path.toString());
        List<String> expectedContents = new LinkedList<>();
        assertThat(true, is(emptyDirContents.equals(expectedContents)));
    }

    /**
     * This test case checks with the sub directories in the given path for java files.
     *
     * @throws IOException when fails to do IO operations
     */
    @Test
    public void emptySubDirScannerTest() throws IOException {

        String dir = baseDir + separator + "scanner3";
        File path = createDirectory(dir);
        String subDir = path.toString() + separator + "subDir1";
        createDirectory(subDir);
        createFile(path, "invalidFile.txt");
        List<String> emptySubDirContents = getJavaFiles(path.toString());
        List<String> expectedContents = new LinkedList<>();
        assertThat(true, is(emptySubDirContents.equals(expectedContents)));
    }

}
