package pl.edu.pw.mini.sg.matrix.calc


import argonaut.Parse
import java.io.File
import org.rogach.scallop.ScallopConf
import pl.edu.pw.mini.sg.matrix.deterministic.{ InitialMatrixGame, MatrixGame, MatrixGamePlugin }


object Calc {
  def main(args: Array[String]) : Unit = {
    val options = new Options(args)
    val gameConfig = MatrixGamePlugin.readConfig(options.game()).get
    val game = InitialMatrixGame(gameConfig)
    val defenderStrategy = {
      val dec = Parse.decode[Vector[(Int, Double)]](options.defenderStrategy()).left.map(x => new RuntimeException(x.toString)).toTry.get
      require(dec.forall(_._2 >= 0), "Probabilities are not nonnegative")
      require(dec.forall(_._2 <= 1), "Probability exceeds 1")
      require(Math.abs(dec.map(_._2).sum - 1) < 1e-2, "Probabilities do not sum to 0")

      dec
    }

    val attackerStrategy = {
      val dec = Parse.decode[Vector[(Int, Double)]](options.attackerStrategy()).left.map(x => new RuntimeException(x.toString)).toTry.get
      require(dec.forall(_._2 >= 0), "Probabilities are not nonnegative")
      require(dec.forall(_._2 <= 1), "Probability exceeds 1")
      require(Math.abs(dec.map(_._2).sum - 1) < 1e-2, "Probabilities do not sum to 0")

      dec
    }

    val result = (for {
      am <- attackerStrategy
      dm <- defenderStrategy
    } yield {
      val prob = am._2*dm._2
      val g = game.makeMove(dm._1, am._1)
      (g.defenderPayoff * prob, g.attackerPayoff * prob)
    }).fold((0.0,0.0)){case ((d1, a1), (d2, a2)) => (d1+d2, a1+a2)}

    Console.println(result)
  }


  private[Calc] final class Options(args: Seq[String]) extends ScallopConf(args) {
    val game = opt[File](name="game", short='g', required=true)
    val defenderStrategy = opt[String](name="defender-strategy", short='d', required=true)
    val attackerStrategy = opt[String](name="attacker-strategy", short='a', required=true)

    verify()
  }
}
