<commit_before>package org.jetbrains.plugins.scala.lang.formatting.scalafmt.dynamic

import com.intellij.openapi.progress.ProcessCanceledException
import org.apache.ivy.util.{AbstractMessageLogger, MessageLogger}
import org.jetbrains.plugins.scala.DependencyManagerBase
import org.jetbrains.plugins.scala.DependencyManagerBase._
import org.jetbrains.plugins.scala.lang.formatting.scalafmt.dynamic.ScalafmtDynamicDownloader._
import org.scalafmt.dynamic.{Dependency, ScalafmtVersion}

import java.net.URL
import java.nio.file.Path
import scala.util.control.NonFatal

class ScalafmtDynamicDownloader(
  extraResolvers: Seq[Resolver],
  progressListener: DownloadProgressListener
) {

  def download(version: ScalafmtVersion): Either[DownloadFailure, DownloadSuccess] =
    try {
      val dependencies = Dependency.dependencies(version)
        .map(x => (x.group % x.artifact % x.version).transitive())
      val resolver = new ScalafmtDependencyResolver(extraResolvers, progressListener)
      val resolvedDependencies = resolver.resolve(dependencies: _*)
      val jars: Seq[Path] = resolvedDependencies.map(_.file.toPath)
      val urls = jars.map(_.toUri.toURL)
      Right(DownloadSuccess(version, urls))
    } catch {
      case e: ProcessCanceledException => throw e
      case NonFatal(e) => Left(DownloadFailure(version, e))
    }

}

object ScalafmtDynamicDownloader {
  sealed trait DownloadResult {
    def version: ScalafmtVersion
  }
  case class DownloadSuccess(override val version: ScalafmtVersion, jarUrls: Seq[URL]) extends DownloadResult
  case class DownloadFailure(override val version: ScalafmtVersion, cause: Throwable) extends DownloadResult

  trait DownloadProgressListener {
    def progressUpdate(message: String): Unit
    def doProgress(): Unit = ()
  }

  object DownloadProgressListener {
    val NoopProgressListener: DownloadProgressListener = _ => {}
  }

  private class ScalafmtDependencyResolver(
    extraResolvers: Seq[Resolver],
    progressListener: DownloadProgressListener
  ) extends DependencyManagerBase {

    // first search in the provided resolvers, then fallback to the default ones
    // but only use resolvers with http(s) protocol, to avoid problems with private repositories.
    // (like gcs, s3, etc.) This is fine since scalafmt should always be published to a public repo.
    override protected def resolvers: Seq[Resolver] = {
      val HttpUrl = "(https?://.*)".r
      (extraResolvers ++ super.resolvers).filter {
        case MavenResolver(_, HttpUrl(_)) => true
        case IvyResolver(_, HttpUrl(_))=> true
        case _ => false
      }
    }

    override protected val logLevel: Int = org.apache.ivy.util.Message.MSG_INFO

    override def createLogger: MessageLogger = new AbstractMessageLogger {
      override def doEndProgress(msg: String): Unit = progressListener.progressUpdate(format(msg))
      override def log(msg: String, level: Int): Unit = progressListener.progressUpdate(format(msg))
      override def rawlog(msg: String, level: Int): Unit = ()
      override def doProgress(): Unit = progressListener.doProgress()
    }

    @inline
    private def format(str: String): String = {
      firstLine(str).trim
    }

    private def firstLine(str: String): String = {
      val strTrimmed = str<commit_msg>scalafmt: add a comment with a link to a issue for a workaround<commit_after>package org.jetbrains.plugins.scala.lang.formatting.scalafmt.dynamic

import com.intellij.openapi.progress.ProcessCanceledException
import org.apache.ivy.util.{AbstractMessageLogger, MessageLogger}
import org.jetbrains.plugins.scala.DependencyManagerBase
import org.jetbrains.plugins.scala.DependencyManagerBase._
import org.jetbrains.plugins.scala.lang.formatting.scalafmt.dynamic.ScalafmtDynamicDownloader._
import org.scalafmt.dynamic.{Dependency, ScalafmtVersion}

import java.net.URL
import java.nio.file.Path
import scala.util.control.NonFatal

class ScalafmtDynamicDownloader(
  extraResolvers: Seq[Resolver],
  progressListener: DownloadProgressListener
) {

  def download(version: ScalafmtVersion): Either[DownloadFailure, DownloadSuccess] =
    try {
      val dependencies = Dependency.dependencies(version)
        .map(x => (x.group % x.artifact % x.version).transitive())
      val resolver = new ScalafmtDependencyResolver(extraResolvers, progressListener)
      val resolvedDependencies = resolver.resolve(dependencies: _*)
      val jars: Seq[Path] = resolvedDependencies.map(_.file.toPath)
      val urls = jars.map(_.toUri.toURL)
      Right(DownloadSuccess(version, urls))
    } catch {
      case e: ProcessCanceledException => throw e
      case NonFatal(e) => Left(DownloadFailure(version, e))
    }

}

object ScalafmtDynamicDownloader {
  sealed trait DownloadResult {
    def version: ScalafmtVersion
  }
  case class DownloadSuccess(override val version: ScalafmtVersion, jarUrls: Seq[URL]) extends DownloadResult
  case class DownloadFailure(override val version: ScalafmtVersion, cause: Throwable) extends DownloadResult

  trait DownloadProgressListener {
    def progressUpdate(message: String): Unit
    def doProgress(): Unit = ()
  }

  object DownloadProgressListener {
    val NoopProgressListener: DownloadProgressListener = _ => {}
  }

  private class ScalafmtDependencyResolver(
    extraResolvers: Seq[Resolver],
    progressListener: DownloadProgressListener
  ) extends DependencyManagerBase {

    // first search in the provided resolvers, then fallback to the default ones
    // Workaround for SCL-19488:
    // but only use resolvers with http(s) protocol, to avoid problems with private repositories.
    // (like gcs, s3, etc.) This is fine since scalafmt should always be published to a public repo.
    override protected def resolvers: Seq[Resolver] = {
      val HttpUrl = "(https?://.*)".r
      (extraResolvers ++ super.resolvers).filter {
        case MavenResolver(_, HttpUrl(_)) => true
        case IvyResolver(_, HttpUrl(_))=> true
        case _ => false
      }
    }

    override protected val logLevel: Int = org.apache.ivy.util.Message.MSG_INFO

    override def createLogger: MessageLogger = new AbstractMessageLogger {
      override def doEndProgress(msg: String): Unit = progressListener.progressUpdate(format(msg))
      override def log(msg: String, level: Int): Unit = progressListener.progressUpdate(format(msg))
      override def rawlog(msg: String, level: Int): Unit = ()
      override def doProgress(): Unit = progressListener.doProgress()
    }

    @inline
    private def format(str: String): String = {
      firstLine(str).trim
    }

    private def firstLine(str: String): String = {
      val strTrimmed = str
{'fraction_non_alphanumeric': 0.09224538773061347, 'fraction_numerical': 0.0010499475026248687, 'mean_word_length': 4.1609907120743035, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6993444', 'n_tokens_mistral': 1888, 'n_tokens_neox': 1821, 'n_words': 482}