/*
 * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
 * 项目名称：Java 信息安全性设计准则
 * 项目描述：用于检查Java源代码的安全性设计准则的Sonarqube插件
 * 版权说明：本软件属北京关键科技股份有限公司所有，在未获得北京关键科技股份有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.keyware.sonar.java.utils;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * Duplicates org.sonar.java.checks.verifier.FilesUtils to locate test jars within the custom-rules plugin
 */
public class FilesUtils {

  private FilesUtils() {
  }

  /**
   * Default location of the jars/zips to be taken into account when performing the analysis.
   */
  private static final String DEFAULT_TEST_JARS_DIRECTORY = "target/test-jars";

  public static List<File> getClassPath(String jarsDirectory) {
    List<File> classpath = new LinkedList<>();
    Path testJars = Paths.get(jarsDirectory);
    if (testJars.toFile().exists()) {
      classpath = getFilesRecursively(testJars, "jar", "zip");
    } else if (!DEFAULT_TEST_JARS_DIRECTORY.equals(jarsDirectory)) {
      throw new AssertionError("The directory to be used to extend class path does not exists ("
        + testJars.toAbsolutePath()
        + ").");
    }
    classpath.add(new File("target/test-classes"));
    return classpath;
  }

  private static List<File> getFilesRecursively(Path root, String... extensions) {
    final List<File> files = new ArrayList<>();

    FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
      @Override
      public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) {
        for (String extension : extensions) {
          if (filePath.toString().endsWith("."
            + extension)) {
            files.add(filePath.toFile());
            break;
          }
        }
        return FileVisitResult.CONTINUE;
      }

      @Override
      public FileVisitResult visitFileFailed(Path file, IOException exc) {
        return FileVisitResult.CONTINUE;
      }
    };

    try {
      Files.walkFileTree(root, visitor);
    } catch (IOException e) {
      // we already ignore errors in the visitor
    }

    return files;
  }

}
