/* sbt -- Simple Build Tool
 * Copyright 2009 Mark Harrah
 */
package sbt

import scala.collection.{mutable, Map, Set}

sealed trait trait ProductsSources extends java.lang.Object with NotNullProductsSources extends NotNullNotNull
{
	def => Iterable[sbt.Path]products: Iterable[sbt.Path]Iterable[Path]
	def => Iterable[sbt.Path]sources: Iterable[sbt.Path]Iterable[Path]
}
sealed trait trait ProductsWrapper extends java.lang.Object with NotNull with ScalaObjectProductsWrapper extends NotNullNotNull
{
	def (=> Iterable[sbt.Path])sbt.ProductsSourcesfrom(=> Iterable[sbt.Path]sources: => Iterable[Path]): sbt.ProductsSourcesProductsSources = (sbt.PathFinder)sbt.ProductsSourcesfrom(object sbt.PathPath.(=> Iterable[sbt.Path])sbt.PathFinderlazyPathFinder(=> Iterable[sbt.Path]sources))
	def (sbt.PathFinder)sbt.ProductsSourcesfrom(sbt.PathFindersources: sbt.PathFinderPathFinder): sbt.ProductsSourcesProductsSources
}
/** Provides methods to define tasks with basic conditional execution based on the sources
* and products of the task. */
trait trait FileTasks extends java.lang.Object with sbt.Project with ScalaObjectFileTasks extends sbt.ProjectProject
{
	implicit def implicit sbt.FileTasks.wrapProduct : (=> sbt.Path)sbt.ProductsWrapperwrapProduct(=> sbt.Pathproduct: => Path): sbt.ProductsWrapperProductsWrapper = object sbt.FileTasksFileTasks.implicit sbt.FileTasks.wrapProduct : (=> sbt.Path)sbt.ProductsWrapperwrapProduct(=> sbt.Pathproduct)
	implicit def implicit sbt.FileTasks.wrapProducts : (=> Iterable[sbt.Path])sbt.ProductsWrapperwrapProducts(=> Iterable[sbt.Path]productsList: => Iterable[Path]): sbt.ProductsWrapperProductsWrapper = object sbt.FileTasksFileTasks.implicit sbt.FileTasks.wrapProducts : (=> Iterable[sbt.Path])sbt.ProductsWrapperwrapProducts(=> Iterable[sbt.Path]productsList)
	/** Runs 'action' if the given products are out of date with respect to the given sources. */
	def (String,sbt.ProductsSources)(=> Option[String])FileTasks.this.TaskfileTask(Stringlabel: StringString, sbt.ProductsSourcesfiles: sbt.ProductsSourcesProductsSources)(=> Option[String]action: => Option[String]): FileTasks.this.TaskTask =
		(=> Option[String])FileTasks.this.Tasktask { object sbt.FileTasksFileTasks.(String,sbt.ProductsSources,sbt.Logger)(=> Option[String])Option[String]runOption(Stringlabel, sbt.ProductsSourcesfiles, => sbt.Loggerlog)(=> Option[String]action) }
	/** Runs 'action' if any of the given products do not exist. */
	def (String,=> Iterable[sbt.Path])(=> Option[String])FileTasks.this.TaskfileTask(Stringlabel: StringString, => Iterable[sbt.Path]products: => Iterable[Path])(=> Option[String]action: => Option[String]): FileTasks.this.TaskTask =
		(=> Option[String])FileTasks.this.Tasktask { object sbt.FileTasksFileTasks.(String,Iterable[sbt.Path],sbt.Logger)(=> Option[String])(=> Option[String])Option[String]existenceCheck[Option[String]Option[String]](Stringlabel, => Iterable[sbt.Path]products, => sbt.Loggerlog)(=> Option[String]action)(object NoneNone) }
		
	/** Creates a new task that performs 'action' only when the given products are out of date with respect to the given sources.. */
	def (sbt.ProductsSources)(=> Option[String])FileTasks.this.TaskfileTask(sbt.ProductsSourcesfiles: sbt.ProductsSourcesProductsSources)(=> Option[String]action: => Option[String]): FileTasks.this.TaskTask = (String,sbt.ProductsSources)(=> Option[String])FileTasks.this.TaskfileTask(java.lang.String("")"", sbt.ProductsSourcesfiles)(=> Option[String]action)
	/** Creates a new task that performs 'action' only when at least one of the given products does not exist.. */
	def (=> Iterable[sbt.Path])(=> Option[String])FileTasks.this.TaskfileTask(=> Iterable[sbt.Path]products: => Iterable[Path])(=> Option[String]action: => Option[String]): FileTasks.this.TaskTask = (String,=> Iterable[sbt.Path])(=> Option[String])FileTasks.this.TaskfileTask(java.lang.String("")"", => Iterable[sbt.Path]products)(=> Option[String]action)
	
}
object object sbt.FileTasksFileTasks
{
	implicit def implicit sbt.FileTasks.wrapProduct : (=> sbt.Path)sbt.ProductsWrapperwrapProduct(=> sbt.Pathproduct: => Path): sbt.ProductsWrapperProductsWrapper = implicit sbt.FileTasks.wrapProducts : (=> Iterable[sbt.Path])sbt.ProductsWrapperwrapProducts(=> sbt.Pathproduct (sbt.Path)List[sbt.Path]:: object NilNil)
	implicit def implicit sbt.FileTasks.wrapProducts : (=> Iterable[sbt.Path])sbt.ProductsWrapperwrapProducts(=> Iterable[sbt.Path]productsList: => Iterable[Path]): sbt.ProductsWrapperProductsWrapper =
		template $anon extends java.lang.Object with sbt.ProductsWrappernew sbt.ProductsWrapperProductsWrapper
		{
			def (sbt.PathFinder)java.lang.Object with sbt.ProductsSources{def sources: scala.collection.Set[sbt.Path]}from(sbt.PathFindersourceFinder: sbt.PathFinderPathFinder) =
				template $anon extends java.lang.Object with sbt.ProductsSourcesnew sbt.ProductsSourcesProductsSources
				{
					def => Iterable[sbt.Path]products = => Iterable[sbt.Path]productsList
					def => scala.collection.Set[sbt.Path]sources = sbt.PathFindersourceFinder.=> scala.collection.Set[sbt.Path]get
				}
		}
	/** Runs 'ifOutofdate' if the given products are out of date with respect to the given sources.*/
	def (String,sbt.ProductsSources,sbt.Logger)(=> Option[String])Option[String]runOption(Stringlabel: StringString, sbt.ProductsSourcesfiles: sbt.ProductsSourcesProductsSources, sbt.Loggerlog: sbt.LoggerLogger)(=> Option[String]ifOutofdate: => Option[String]): Option[String]Option[String] =
	{
		val Option[String]result = (String,sbt.ProductsSources,sbt.Logger)(=> Option[String])(=> Option[String])Option[String]apply[Option[String]Option[String]](Stringlabel, sbt.ProductsSourcesfiles, sbt.Loggerlog)(=> Option[String]ifOutofdate)(object NoneNone)
		Anyif(Option[String]result.=> BooleanisDefined)
			object sbt.FileUtilitiesFileUtilities.(Iterable[sbt.Path],Boolean,sbt.Logger)Option[String]clean(sbt.ProductsSourcesfiles.=> Iterable[sbt.Path]products, Boolean(true)true, sbt.Loggerlog)
		Option[String]result
	}
	/** Returns 'ifOutofdate' if the given products are out of date with respect to the given sources.  Otherwise, returns ifUptodate. */
	def [T](String,sbt.ProductsSources,sbt.Logger)(=> T)(=> T)Tapply[>: Nothing <: AnyT](Stringlabel: StringString, sbt.ProductsSourcesfiles: sbt.ProductsSourcesProductsSources, sbt.Loggerlog: sbt.LoggerLogger)(=> TifOutofdate: => T)(=> TifUptodate: => T): TT =
	{
		val Iterable[sbt.Path]products = sbt.ProductsSourcesfiles.=> Iterable[sbt.Path]products
		(String,Iterable[sbt.Path],sbt.Logger)(=> T)(=> T)TexistenceCheck[TT](Stringlabel, Iterable[sbt.Path]products, sbt.Loggerlog)(=> TifOutofdate)
		{
			val Iterable[sbt.Path]sources = sbt.ProductsSourcesfiles.=> Iterable[sbt.Path]sources
			Tif(Iterable[sbt.Path]sources.=> BooleanisEmpty)
			{
				sbt.Loggerlog.(=> String)Unitdebug(java.lang.String("Running ")"Running " (Any)java.lang.String+ Stringlabel (Any)java.lang.String+ java.lang.String(" task because no sources exist.")" task because no sources exist.")
				=> TifOutofdate
			}
			else
			{
				val LongoldestProductModifiedTime = (Iterable[sbt.Path])Iterable[Long]mapLastModified(Iterable[sbt.Path]products).((Long, Long) => Long)LongreduceLeft(implicit scala.Predef.longWrapper : (Long)scala.runtime.RichLong_ (Long)Longmin Long_)
				val LongnewestSourceModifiedTime = (Iterable[sbt.Path])Iterable[Long]mapLastModified(Iterable[sbt.Path]sources).((Long, Long) => Long)LongreduceLeft(implicit scala.Predef.longWrapper : (Long)scala.runtime.RichLong_ (Long)Longmax Long_)
				Tif(LongoldestProductModifiedTime (Long)Boolean< LongnewestSourceModifiedTime)
				{
					Unitif(sbt.Loggerlog.(sbt.Level.Value)BooleanatLevel(object sbt.LevelLevel.=> sbt.Level.ValueDebug))
					{
						sbt.Loggerlog.(=> String)Unitdebug(java.lang.String("Running ")"Running " (Any)java.lang.String+ Stringlabel (Any)java.lang.String+ java.lang.String(" task because the following sources are newer than at least one product: ")" task because the following sources are newer than at least one product: ")
						(Iterable[sbt.Path],sbt.Logger)UnitlogDebugIndented(Iterable[sbt.Path]sources.((sbt.Path) => Boolean)Iterable[sbt.Path]filter(sbt.Path_.=> LonglastModified (Long)Boolean> LongoldestProductModifiedTime), sbt.Loggerlog)
						sbt.Loggerlog.(=> String)Unitdebug(java.lang.String(" The following products are older than at least one source: ")" The following products are older than at least one source: ")
						(Iterable[sbt.Path],sbt.Logger)UnitlogDebugIndented(Iterable[sbt.Path]products.((sbt.Path) => Boolean)Iterable[sbt.Path]filter(sbt.Path_.=> LonglastModified (Long)Boolean< LongnewestSourceModifiedTime), sbt.Loggerlog)
					}
					=> TifOutofdate
				}
				else
					=> TifUptodate
			}
		}
	}
	/** Checks that all 'products' exist.  If they do, 'ifAllExists' is returned, otherwise 'products' is returned.*/
	private def [T](String,Iterable[sbt.Path],sbt.Logger)(=> T)(=> T)TexistenceCheck[>: Nothing <: AnyT](Stringlabel: StringString, Iterable[sbt.Path]products: Iterable[sbt.Path]Iterable[Path], sbt.Loggerlog: sbt.LoggerLogger)(=> Taction: => T)(=> TifAllExist: => T) =
	{
		val Iterable[sbt.Path]nonexisting = Iterable[sbt.Path]products.((sbt.Path) => Boolean)Iterable[sbt.Path]filter(=> Boolean!sbt.Path_.=> Booleanexists)
		Tif(Iterable[sbt.Path]nonexisting.=> BooleanisEmpty)
			=> TifAllExist
		else
		{
			Unitif(sbt.Loggerlog.(sbt.Level.Value)BooleanatLevel(object sbt.LevelLevel.=> sbt.Level.ValueDebug))
			{
				sbt.Loggerlog.(=> String)Unitdebug(java.lang.String("Running ")"Running " (Any)java.lang.String+ Stringlabel (Any)java.lang.String+ java.lang.String(" task because at least one product does not exist:")" task because at least one product does not exist:")
				(Iterable[sbt.Path],sbt.Logger)UnitlogDebugIndented(Iterable[sbt.Path]nonexisting, sbt.Loggerlog)
			}
			=> Taction
		}
	}
	private def [T](Iterable[T],sbt.Logger)UnitlogDebugIndented[>: Nothing <: AnyT](Iterable[T]it: Iterable[T]Iterable[T], sbt.Loggerlog: sbt.LoggerLogger) { Iterable[T]it.((T) => Unit)Unitforeach(Tx => sbt.Loggerlog.(=> String)Unitdebug(java.lang.String("\011")"\t" (Any)java.lang.String+ Tx)) }
	private def (Iterable[sbt.Path])Iterable[Long]mapLastModified(Iterable[sbt.Path]paths: Iterable[sbt.Path]Iterable[Path]): Iterable[Long]Iterable[Long] = Iterable[sbt.Path]paths.((sbt.Path) => Long)Iterable[Long]map(sbt.Path_.=> LonglastModified)
}