/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.streampark.common.util

import org.apache.streampark.common.Constant

import java.io.{File, IOException}
import java.net.{URL, URLClassLoader}
import java.util.function.Supplier

import scala.collection.mutable.ArrayBuffer

object ClassLoaderUtils extends Logger {

  private[this] val originalClassLoader: ClassLoader = Thread.currentThread().getContextClassLoader

  /**
   * Execute with the specified classloader for scala API
   *
   * @param targetClassLoader
   * @param func
   * @tparam R
   * @return
   */
  def runAsClassLoader[R](targetClassLoader: ClassLoader, func: () => R): R = {
    try {
      Thread.currentThread.setContextClassLoader(targetClassLoader)
      func()
    } catch {
      case e: Exception => throw e
    } finally {
      Thread.currentThread.setContextClassLoader(originalClassLoader)
    }
  }

  /**
   * Execute with the specified classloader for JavaAPI
   *
   * @param targetClassLoader
   * @param supplier
   * @tparam R
   * @return
   */
  def runAsClassLoader[R](targetClassLoader: ClassLoader, supplier: Supplier[R]): R = {
    try {
      Thread.currentThread.setContextClassLoader(targetClassLoader)
      supplier.get()
    } catch {
      case e: Exception => throw e
    } finally {
      Thread.currentThread.setContextClassLoader(originalClassLoader)
    }
  }
  @throws[IOException]
  def cloneClassLoader(): ClassLoader = {
    val urls = originalClassLoader.getResources(".")
    val buffer = ArrayBuffer[URL]()
    while (urls.hasMoreElements) {
      buffer += urls.nextElement()
    }
    new URLClassLoader(buffer.toArray[URL], originalClassLoader)
  }

  def loadJar(jarFilePath: String): Unit = {
    val jarFile = new File(jarFilePath)
    require(
      jarFile.exists,
      s"[StreamPark] ClassLoaderUtils.loadJar: jarFilePath $jarFilePath is not exists")
    require(
      jarFile.isFile,
      s"[StreamPark] ClassLoaderUtils.loadJar: jarFilePath $jarFilePath is not file")
    loadPath(jarFile.getAbsolutePath)
  }

  def loadJars(path: String): Unit = {
    val jarDir = new File(path)
    require(jarDir.exists, s"[StreamPark] ClassLoaderUtils.loadJars: jarPath $path is not exists")
    require(
      jarDir.isDirectory,
      s"[StreamPark] ClassLoaderUtils.loadJars: jarPath $path is not directory")
    require(
      jarDir.listFiles.length > 0,
      s"[StreamPark] ClassLoaderUtils.loadJars: have not jar in path:$path")
    jarDir.listFiles.foreach(x => loadPath(x.getAbsolutePath))
  }

  def loadResource(filepath: String): Unit = {
    val file = new File(filepath)
    addURL(file)
  }

  def loadResourceDir(filepath: String): Unit = {
    val file = new File(filepath)
    loopDirs(file)
  }

  private[this] def loadPath(
      filepath: String,
      ext: List[String] = List(Constant.JAR_SUFFIX, Constant.ZIP_SUFFIX)): Unit = {
    val file = new File(filepath)
    loopFiles(file, ext)
  }

  private[this] def loopDirs(file: File): Unit = {
    if (file.isDirectory) {
      addURL(file)
      file.listFiles.foreach(loopDirs)
    }
  }

  private[this] def loopFiles(file: File, ext: List[String] = List()): Unit = {
    if (file.isDirectory) {
      file.listFiles.foreach(x => loopFiles(x, ext))
    } else {
      if (ext.isEmpty) {
        addURL(file)
      } else if (ext.exists(x => file.getName.endsWith(x))) {
        Utils.requireCheckJarFile(file.toURI.toURL)
        addURL(file)
      }
    }
  }

  @throws[Exception]
  private[this] def addURL(file: File): Unit = {
    val classLoader = ClassLoader.getSystemClassLoader
    classLoader match {
      case c if c.isInstanceOf[URLClassLoader] =>
        val addURL = classOf[URLClassLoader].getDeclaredMethod("addURL", Array(classOf[URL]): _*)
        addURL.setAccessible(true)
        addURL.invoke(c, file.toURI.toURL)
      case _ =>
        val field = classLoader.getClass.getDeclaredField("ucp")
        field.setAccessible(true)
        val ucp = field.get(classLoader)
        val addURL = ucp.getClass.getDeclaredMethod("addURL", Array(classOf[URL]): _*)
        addURL.setAccessible(true)
        addURL.invoke(ucp, file.toURI.toURL)
    }
  }
}
