import junit.framework.Assert;
import junit.framework.TestCase;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import csce913proj1.CdbTuple;


public class Test extends TestCase{


	
	public static void main(String [] args)
	{
		ABMatrix m = new ABMatrix();
		File file = new File(args[0]);
		FileInputStream filein = null;
		BufferedInputStream streamin = null;
		DataInputStream datain = null;
		String l=null;
		String stemp=null; 
		int i=0;
		int j=0;
		int k=0;
		char[] temp = new char[20];

		    try {
		    //Open file streams
		      filein = new FileInputStream(file);
		      streamin = new BufferedInputStream(filein);
		      datain = new DataInputStream(streamin);
	
		      //Number of Varaible *2 for the positive and negative versions
		      m.M = 2*(Integer.valueOf(datain.readLine()));
			  System.out.println("There are "+m.M/2+" variables");
			  
			  //Instantiate m varaible names and matrix
			  m.names = new String[m.M];
			  m.matrix = new double[m.M][m.M];
		    		for (i=0; i<m.M; i++)

		    			for (j=0; j<m.M; j++)

		    			{

		    				m.matrix[i][j] = Double.NEGATIVE_INFINITY;

		    			}
		    		
		    	//Read in each Constraint	
		     while (datain.available() != 0) 
		     {		    		
		    	 //Read in a line where there is a constraint
		    		l=datain.readLine();
		    		System.out.println(l);
		    		temp = l.toCharArray(); 
		    		i=0;
		    		j=0;
		    		k=0;
		    		
		    		//Read in the first variable and see if it is already in the list of names
		    		//If the first variable is positive then there will not be a + sign
		    			if(temp[i]=='-')
		    			{
		    				i++;
		    				j=m.findname(temp[i], 1);
		    			}
		    			else
		    			{
		    				j=m.findname(temp[i], 0);
		    			}
		    			i++;
		    			
		    			
			    		//Read in the second variable and see if it is already in the list of names
			    		//If the second variable is positive then there will be a + sign and not --
			    		//If the second variable is negative then there will be a - sign and not +-
		    			if(temp[i]=='-')
		    			{
		    				i++;
		    				k=m.findname(temp[i], 0);
		    			}
		    			else
		    			{
		    				i++;
		    				k=m.findname(temp[i], 1);
		    			}
		    			i=i+3;
		    			//Enter in the value
			    		stemp=String.valueOf(temp, i, (temp.length-i));
			    		m.matrix[j][k] = Integer.valueOf(stemp); 
			    		stemp=null;
		     }
				      
		    		CdbTuple t = new CdbTuple(m, m.names);

		    		//See if it is satisfiable
		    		boolean flag = t.satisfiable();
			        System.out.println("The solution was "+flag);


		      filein.close();
		      streamin.close();
		      datain.close();

		    } catch (FileNotFoundException e) {
		      e.printStackTrace();
		    } catch (IOException e) {
		      e.printStackTrace();
		    }
	}


	/**

	 * This SIMPLE test should return satisfiable

	 * @param filename

	 */

	public void testSimpleSat()

	{
		ABMatrix m = new ABMatrix();
		m.matrix = new double[5][5];
		for (int i=0; i<5; i++)
			for (int j=0; j<5; j++)
			{
				m.matrix[i][j] = Double.NEGATIVE_INFINITY;
			}
		m.matrix[1][0] = 5; // x-y >= 5
		m.matrix[0][1] = -10; // -x+y >= -10
		m.M = 5;

		CdbTuple t = new CdbTuple(m, new String[] {"x", "y", "z", "x1", "z1"});
		boolean flag = t.satisfiable();
		Assert.assertTrue(flag);
	}

	

	public void testSimpleUnsat()
	{
		ABMatrix m = new ABMatrix();
		m.matrix = new double[5][5];
		for (int i=0; i<5; i++)
			for (int j=0; j<5; j++)
			{
				m.matrix[i][j] = Double.NEGATIVE_INFINITY;
			}
		m.matrix[1][0] = 12; // x-y >= 12
		m.matrix[0][1] = -10; // -x+y >= -10
		m.M = 5;
		
		CdbTuple t = new CdbTuple(m, new String[] {"x", "y", "z", "x1", "z1"});
		boolean flag = t.satisfiable();
		Assert.assertTrue(!flag);
	}

	public void testAddSat()
	{
		ABMatrix m = new ABMatrix();
		m.matrix = new double[5][5];
		m.M = 5;

		for (int i=0; i<5; i++)
			for (int j=0; j<5; j++)
			{
				m.matrix[i][j] = Double.NEGATIVE_INFINITY;
			}
		m.matrix[1][0] = 5; // x-y >= 5
		m.matrix[0][1] = -10; // x+y >= -10
		m.matrix[2][1] = 3; // -x-y >= -10
		m.matrix[2][3] = -5; // +x+y >= -10

		CdbTuple t = new CdbTuple(m, new String[] {"xp", "yp", "xn", "yn", "z1"});
		boolean flag = t.satisfiable();
		Assert.assertTrue(flag);
	}
	
	public void testSat2() {
        dm.matrix = new double[5][5];
        am.matrix = new double[5][5];
        mm.matrix = new double[5][5];
        dm.M = 5;
        am.M = 5;
        mm.M = 5;
        // Initialize matrices with positive infinity weights
        for (int i=0; i<5; i++) {
            for (int j=0; j<5; j++) {
            dm.matrix[i][j] = Double.POSITIVE_INFINITY;
            am.matrix[i][j] = Double.POSITIVE_INFINITY;
            mm.matrix[i][j] = Double.POSITIVE_INFINITY;
            }
        }
        
        //Set of SATISFIABLE addition constraints
        dm.matrix[2][3] = 10;    // -x+y <= 10
        dm.matrix[4][2] = -5;    //  x-z <= -5
        dm.matrix[0][1] = 0;     //    w <= 0
        dm.matrix[1][0] = 3;     //   -w <= 3
        am.matrix[1][2] = 6;  //  w+x <= 6
        mm.matrix[4][3] = 0;  // -y-z <= 0
        
        
        
        CdbTuple t = new CdbTuple(dm, am, mm, new String[] {"0", "w", "x", "y", "z"});
        boolean flag = t.satisfiable();
        assert(flag==true);
	}
	
	public void testUnsat2() {
        dm.matrix = new double[5][5];
        am.matrix = new double[5][5];
        mm.matrix = new double[5][5];
        dm.M = 5;
        am.M = 5;
        mm.M = 5;
        // Initialize matrices with positive infinity weights
        for (int i=0; i<5; i++) {
            for (int j=0; j<5; j++) {
            dm.matrix[i][j] = Double.POSITIVE_INFINITY;
            am.matrix[i][j] = Double.POSITIVE_INFINITY;
            mm.matrix[i][j] = Double.POSITIVE_INFINITY;
            }
        }
        
        // Set of UNSATISFIABLE addition constraints
        dm.matrix[4][2] = -3;    // x-z <= -3
        dm.matrix[4][3] = 8;     // y-z <= 8
        dm.matrix[3][1] = 2;     // w-y <= 2
        dm.matrix[2][1] = -4;    // w-x <= -4
        dm.matrix[1][0] = -40;   // -w <= -40
        dm.matrix[0][4] = 20;    // z <= 20
        
        CdbTuple t = new CdbTuple(dm, am, mm, new String[] {"0", "w", "x", "y", "z"});
        boolean flag = t.satisfiable();
        assert(flag==true);
	}
	
	public void testSat3() {
		dm.matrix = new double[3][3];
       	am.matrix = new double[3][3];
	    mm.matrix = new double[3][3];
	    dm.M = 3;
	    am.M = 3;
	    mm.M = 3;
	    // Initialize matrices with positive infinity weights
	    for (int i=0; i<3; i++) {
	        for (int j=0; j<3; j++) {
	        dm.matrix[i][j] = Double.POSITIVE_INFINITY;
	        am.matrix[i][j] = Double.POSITIVE_INFINITY;
	        mm.matrix[i][j] = Double.POSITIVE_INFINITY;
	        }
	    }
	    
	    // Set of UNSATISFIABLE addition constraints
	    dm.matrix[2][1] = 10;    // x-y >= 10
	    dm.matrix[1][2] = -10;   // y-x >= -10
	    am.matrix[1][2] = 10;    // x+y >= 10
	    	    
	    CdbTuple t = new CdbTuple(dm, am, mm, new String[] {"0", "w", "x", "y", "z"});
	    boolean flag = t.satisfiable();
	    assert(flag==true);
	}


}

