package hsr.smart;

import java.util.Scanner;

import edu.neu.ccs.demeterf.lib.List;

import hsr.HSRConfig;
import hsr.HSRInstanceSet;
import hsr.HSRSolution;
import scg.Agreement;
import scg.Claim;
import scg.Config;
import scg.OpposeAction;
import scg.ParseException;
import scg.SolutionI;
import scg.SolveRequest;

public class GameMain {
	static Scanner KEYBOARD = null;
	static List<Claim> forbiddenClaims = List.create();
	static int N = 0; // number of rungs
	static int K = 0; // number of jars
	static int Q = 0; // number of questions
	static Config cfg = HSRConfig.getDefaultConfig();
	static HSRAvatarSmart a = new HSRAvatarSmart(cfg);
	
	public void proposeHandler(){
		String yesorno = KEYBOARD.nextLine();
    	if (yesorno.equals("y")){
			System.out.println("Please give the number of rungs: n");
			N = Integer.parseInt(KEYBOARD.nextLine());
			System.out.println("Please give the number of jars available: k");
			K = Integer.parseInt(KEYBOARD.nextLine());
			System.out.println("Please give the number of questions you need to ask: q");
			Q = Integer.parseInt(KEYBOARD.nextLine());
			double quality = (double) Q / (double) N;
			opposeHandler(N, K, quality);
    	}
    	else if (yesorno.equals("n")){
        	System.out.println("Avatar propose: ");
        	Claim claim = a.propose(forbiddenClaims).lookup(0);
			System.out.println(claim);
			int n = ((HSRInstanceSet) claim.getInstanceSet()).getSingleton().getN();
        	System.out.println("Depth: " + claim.getQuality()*n);
			System.out.println("Please give an oppose action (refute/strengthen/agree)");
			scholarActionHandler(claim, claim.getQuality()*n);
			tryAgain();
    	}
    	else{
			System.out.printf("Please type \"y\" to propose a new claim\n" +
			"or \"n\" to see avatar's claim");
    		proposeHandler();
    	}
	}
	
	public void opposeHandler(int n, int k, double quality){
		try{
			Claim claim = Claim.parse("hsr.HSRInstanceSet {{ HSR (" + N + ","
					+ K + ") }} scg.protocol.ExistsForAll {{ }} " + quality
					+ " 1.0");
			forbiddenClaims.append(claim);
			System.out.println("Your claim is : " + claim);
			List<Claim> claims = List.create(claim);
			OpposeAction action = a.oppose(claims).lookup(0);

			SolveRequest solveRequest = SolveRequest
					.parse("solve hsr.HSRInstance {{ "
							+ ((HSRInstanceSet) claim.getInstanceSet())
									.getSingleton() + " }} " + claim);
			HSRSolution solution = (HSRSolution) a.solve(solveRequest);
			int depth = solution.findDepth();
			double q = (double) depth / (double) N;

			if (Q < depth) {
				System.out
						.println("Avatar refutes your claim: You cann't find a solution with minimum depth of "
								+ Q + " for this instance");
				tryAgain();
			} else {
				System.out
						.println("Avatar's decision to your claim: " + action);
				System.out.println("Avatar's solution quality: " + q);
				System.out.println("Depth/Question number: " + depth);
				System.out.println("Decision tree: " + solution);
				if (q < claim.getQuality()) {
					System.out
							.println("Avatar needs less questions to ask. You lose");
					tryAgain();
				} else if (q > claim.getQuality()){
					System.out.println("You win!");
					tryAgain();
				} else if (q == claim.getQuality()){
					System.out.println("Draw");
					tryAgain();
				}
			}
		} catch (Exception e) {
			System.out.println("Error when parsing " + e);
		}
	}

	public void scholarActionHandler(Claim claim, double avatarDepth) {
		String inputAction = KEYBOARD.nextLine();
		SolveRequest solveRequest;
		try {
			solveRequest = SolveRequest
					.parse("solve hsr.HSRInstance {{ "
							+ ((HSRInstanceSet) claim.getInstanceSet())
									.getSingleton() + " }} " + claim);
			
			HSRSolution solution = (HSRSolution) a.solve(solveRequest);
			if (inputAction.equals("refute")) {
				System.out.println("Avatar's solution: " + solution);
				System.out.println("You lose.");
			} else if (inputAction.equals("strengthen")) {
				System.out.println("Please give the depth/questions you need for this claim:");
				String inputDepth = KEYBOARD.nextLine();
				int depth = Integer.parseInt(inputDepth);
				if (depth < avatarDepth){
					System.out.println("You win!");
				} else {
					System.out.println("You lose.");
				}
			} else if (inputAction.equals("agree")) {
				System.out.println("Avatar's solution: " + solution);
				System.out.println("Draw");
			}
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	public void tryAgain(){
		System.out.println("Try again? y/n ");
		String tryAgain = KEYBOARD.nextLine();
		if (tryAgain.equals("y")) {
			System.out.printf("Please type \"y\" to propose a new claim\n" +
			"or \"n\" to see avatar's claim");
			proposeHandler();
		} else {
			System.out.println("See you next time.");
			System.exit(0);
		}
	}
	public static void main(String[] args){
			KEYBOARD = new Scanner(System.in);
			System.out.printf("Please type \"y\" to propose a new claim\n" +
					"or \"n\" to see avatar's claim");
			GameMain game = new GameMain();
			game.proposeHandler();
			
//			SolveRequest r = SolveRequest.parse("solve hsr.HSRInstance {{ HSR (25,2) }} hsr.HSRInstanceSet {{ HSR (25,2) }} scg.protocol.ForAllExists {{ }} 0.44444 0.5");
//			System.out.println("request: " + r);
//			SolutionI s = a.solve(r);
//			System.out.println(s);
	}
}
