package sbt

	import complete.{DefaultParsers,Parser}
	import DefaultParsers._
	import Def.ScopedKey
	import Types.idFun
	import java.io.File

object Inspect
{
	sealed trait Mode
	final case class Details(actual: Boolean) extends Mode
	private[this] final class Opt(override val toString: String) extends Mode
	val DependencyTree: Mode = new Opt("tree")
	val Uses: Mode = new Opt("inspect")
	val Definitions: Mode = new Opt("definitions")

	def parser: State => Parser[(Inspect.Mode,ScopedKey[_])] = (s: State) => spacedModeParser(s) flatMap {
		case opt @ (Uses | Definitions) => allKeyParser(s).map(key => (opt, Def.ScopedKey(Global, key)))
		case opt @ (DependencyTree | Details(_)) => spacedKeyParser(s).map(key => (opt, key))
	}
	val spacedModeParser: (State => Parser[Mode]) = (s: State) => {
		val actual = "actual" ^^^ Details(true)
		val tree = "tree" ^^^ DependencyTree
		val uses = "uses" ^^^ Uses
		val definitions = "definitions" ^^^ Definitions
		token(Space ~> (tree | actual | uses | definitions)) ?? Details(false)
	}

	def allKeyParser(s: State): Parser[AttributeKey[_]] =
	{
		val keyMap = Project.structure(s).index.keyMap
		token(Space ~> (ID !!! "Expected key" examples keyMap.keySet)) flatMap { key => Act.getKey(keyMap, key, idFun) }
	}
	val spacedKeyParser: State => Parser[ScopedKey[_]] = (s: State) => Act.requireSession(s, token(Space) ~> Act.scopedKeyParser(s))

	def output(s: State, option: Mode, sk: Def.ScopedKey[_]): String =
	{
		val extracted = Project.extract(s)
			import extracted._
		option match
		{
			case Details(actual) =>
				Project.details(structure, actual, sk.scope, sk.key)
			case DependencyTree =>
				val basedir = new File(Project.session(s).current.build)
				Project.settingGraph(structure, basedir, sk).dependsAscii
			case Uses =>
				Project.showUses(Project.usedBy(structure, true, sk.key))
			case Definitions =>
				Project.showDefinitions(sk.key, Project.definitions(structure, true, sk.key))
		}
	}

}