/*
 * Copyright 2016-2018 the original author or authors.
 *
 * 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.joinfaces.tools;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

@Slf4j
class ClasspathScannerTest {

	private ClasspathScanner classpathScanner;
	private File file;

	@BeforeEach
	void setUp() throws IOException {
		file = Files.createTempDirectory(getClass().getName()).toFile();
		classpathScanner = ClasspathScanner.builder()
				.classGraphConfigurer(c -> c)
				.classpathRoot(file)
				.build();
	}

	@AfterEach
	void deleteTempDir() throws IOException {
		Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {
			@Override
			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
				Files.delete(file);
				return FileVisitResult.CONTINUE;
			}

			@Override
			public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
				Files.delete(dir);
				return FileVisitResult.CONTINUE;
			}
		});
		Files.deleteIfExists(file.toPath());
	}

	@Test
	void scanClasses() throws IOException {
		classpathScanner.scanClasses();

		assertThat(new File(file, "META-INF/joinfaces")).exists();
		assertThat(new File(file, "META-INF/joinfaces")).isDirectory();
	}

	@Test
	void scanClasses_myfaces_sci() throws IOException {
		classpathScanner.scanClasses();

		File classesFile = new File(file, "META-INF/joinfaces/org.apache.myfaces.ee.MyFacesContainerInitializer.classes");
		assertThat(classesFile).isFile();

		List<String> classNames = Files.lines(classesFile.toPath(), StandardCharsets.UTF_8)
				.peek(log::debug)
				.collect(Collectors.toList());

		assertThat(classNames).isNotEmpty();
	}

	@Test
	void scanClasses_mojarra_sci() throws IOException {
		classpathScanner.scanClasses();

		File classesFile = new File(file, "META-INF/joinfaces/com.sun.faces.config.FacesInitializer.classes");
		assertThat(classesFile).isFile();

		List<String> classNames = Files.lines(classesFile.toPath(), StandardCharsets.UTF_8)
				.peek(log::debug)
				.collect(Collectors.toList());

		assertThat(classNames).isNotEmpty();
	}

	@Test
	void scanClasses_myFacesAnnotations() throws IOException {
		classpathScanner.scanClasses();

		File classesFile = new File(file, "META-INF/joinfaces/org.apache.myfaces.spi.AnnotationProvider.classes");
		assertThat(classesFile).isFile();

		List<String> mapEntries = Files.lines(classesFile.toPath(), StandardCharsets.UTF_8)
				.peek(log::debug)
				.collect(Collectors.toList());

		assertThat(mapEntries).isNotEmpty();

		Pattern pattern = Pattern.compile(".+=.?");
		mapEntries.forEach(mapEntry -> assertThat(mapEntry).matches(pattern));
	}
}

@@ -1375,16 +1375,21 @@
 ion %7B%0A%09%09
+this.
 file = F
@@ -1447,16 +1447,21 @@
 le();%0A%09%09
+this.
 classpat
@@ -1551,16 +1551,21 @@
 athRoot(
+this.
 file)%0A%09%09
@@ -1656,16 +1656,21 @@
 ileTree(
+this.
 file.toP
@@ -2083,16 +2083,21 @@
 fExists(
+this.
 file.toP
@@ -2150,32 +2150,37 @@
 IOException %7B%0A%09%09
+this.
 classpathScanner
@@ -2210,32 +2210,37 @@
 rtThat(new File(
+this.
 file, %22META-INF/
@@ -2276,32 +2276,37 @@
 rtThat(new File(
+this.
 file, %22META-INF/
@@ -2391,32 +2391,37 @@
 IOException %7B%0A%09%09
+this.
 classpathScanner
@@ -2459,32 +2459,37 @@
 File = new File(
+this.
 file, %22META-INF/
@@ -2837,32 +2837,37 @@
 IOException %7B%0A%09%09
+this.
 classpathScanner
@@ -2905,32 +2905,37 @@
 File = new File(
+this.
 file, %22META-INF/
@@ -3286,16 +3286,21 @@
 ion %7B%0A%09%09
+this.
 classpat
@@ -3354,16 +3354,21 @@
 ew File(
+this.
 file, %22M

fix checkstyle