/*
 * Copyright 2016 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 org.slf4j.Logger;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.slf4j.LoggerFactory.getLogger;

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

    private final Logger log = getLogger(getClass());

    @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);
            assertNotNull(constructor.newInstance());
        }
    }

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

        String dir = baseDir + File.separator + "scanner2";
        File path = createDirectory(dir);
        createFile(path, "testScanner.java");
        List<String> dirContents = YangFileScanner.getJavaFiles(path.toString());
        List<String> expectedContents = new LinkedList<>();
        expectedContents.add(path.getCanonicalPath() + File.separator + "testScanner.java");
        assertEquals(dirContents, 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
     */
    public 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
     */
    public void createFile(File myDir, String fileName) throws IOException {

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

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

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

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

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

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

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

    /**
     * This test case checks with the sub directories in the given path for java files.

    @Test
    public void exceptionHandleTest() throws IOException {

        String dir = baseDir + File.separator + "scanner4";
        thrown.expect(IOException.class);
        List<String> invalidContents = YangFileScanner.getJavaFiles(dir);
        File path = createDirectory(dir);
        createFile(path, "except.java");
        List<String> dirWithFileName = YangFileScanner
                .getJavaFiles(path + File.separator + "except.java" + File.separator + "scanner5");
    }*/
}
