law(spectrum,authority(ca),language(java))
authority(ca,keyHash(C02BF92156D001021E80D023765104E0))
authority(fcc,keyHash(75F6C335CF87DFC2B047D2105A63DEB7))

public class L extends Law{

	public static final String bank = "bank@rutgers.edu";
	public static final String auditor = "auditor@rutgers.edu";


	public void adopted(String arg, String[] issuer, String[] subject, String[] attributes) { 
	  if (issuer.length != 0) {
	  	if (issuer[0].equals("ca") && subject[0].equals(Self) && attributes[0].equals("role(bank)")) {
		  doAdd("role(bank)");
		}
		if (issuer[0].equals("ca") && subject[0].equals(Self) && attributes[0].equals("role(auditor)")) {
		  doAdd("role(auditor)");
		}
		if (issuer[0].equals("ca") && subject[0].equals(Self) && attributes[0].startsWith("[role(consumer),name(")) {
		 doAdd("role(consumer)");
		 int index = attributes[0].indexOf(","); 
		 String N = attributes[0].substring(index+1, attributes[0].length()-1);
		 doAdd(N);
		}
	  }
	  else{
          	doQuit();
          }
       }
       
       public void certified(String source, String issuer, String subject, String attributes) {
         if (issuer.equals("fcc") && subject.equals(Self)) {
             doAdd("accessible("+attributes+")");
         }
       }
       
       
       
       public void sent(String source, String message, String dest) {
         if (message.equals("getCS")){
		doDiscloseAllCS();
	 }
	 if (message.startsWith("start") && CS.has("role(consumer)")){
	 	String content = getContentFromMessage(message);
	 	int pos1 = content.indexOf("]");
	 	int pos2 = content.indexOf(",",pos1+2);
	 	String block = content.substring(0,pos1+1);
	 	int price = Integer.parseInt(content.substring(pos1+2,pos2));
	 	int t = Integer.parseInt(content.substring(pos2+1,content.length()));
	 	int index1 = block.indexOf("(");
		int index2 = block.indexOf(",");
		int index3 = block.indexOf(",",index2+1);
		int index4 = block.indexOf(")");
		int f1Sale = Integer.parseInt(block.substring(index1+1,index2));
		int f2Sale = Integer.parseInt(block.substring(index2+1,index3));
		String unitSale = block.substring(index3+1,index4);
		int index5 = block.indexOf("(",index4+1);
		int index6 = block.indexOf(",",index5+1);
		int index7 = block.indexOf(")",index6+1);
		int t1Sale = Integer.parseInt(block.substring(index5+1,index6));
		int t2Sale = Integer.parseInt(block.substring(index6+1,index7));
	 	Term terms = CS.deep_clone();
	  	boolean match = false;
	 	for (int i=0; i < terms.getArity() && !(match); i++) {
	 		if ((terms.get(i)).has("[freq(%F1,%F2,%U),time(%T1,%T2)]")) {
	 			UnifyResult spectrumTerm = (terms.get(i)).find("[freq(%F1,%F2,%U),time(%T1,%T2)]");
	 			int f1 = Integer.parseInt((spectrumTerm.getTVar("%F1")).toString());
	 			int f2 = Integer.parseInt((spectrumTerm.getTVar("%F2")).toString());
	 			String unit = (spectrumTerm.getTVar("%U")).toString();
	 			int t1 = Integer.parseInt((spectrumTerm.getTVar("%T1")).toString());
	 			int t2 = Integer.parseInt((spectrumTerm.getTVar("%T2")).toString());
	 			if (unit.equals(unitSale)) {
	 				if ((f1Sale >= f1) && (f2Sale <= f2) && (t1Sale >= t1) && (t2Sale <= t2) && (CS.has("accessible([freq("+f1+","+f2+","+unit+"),time("+t1+","+t2+")])"))) {
	 					match = true;
	 					doRemove("accessible([freq("+f1+","+f2+","+unit+"),time("+t1+","+t2+")])");
	 					if (f1Sale > f1) {
	 						doAdd("accessible([freq("+f1+","+f1Sale+","+unit+"),time("+t1+","+t2+")])");
	 					}
	 					if (f2Sale < f2) {
	 						doAdd("accessible([freq("+f2Sale+","+f2+","+unit+"),time("+t1+","+t2+")])");
	 					}
	 					if (t1Sale > t1) {
	 						doAdd("accessible([freq("+f1Sale+","+f2Sale+","+unit+"),time("+t1+","+t1Sale+")])");
	 					}
	 					if (t2Sale < t2) {
	 						doAdd("accessible([freq("+f1Sale+","+f2Sale+","+unit+"),time("+t2Sale+","+t2+")])");
	 					}
	 					doImposeObligation("sale("+block+","+price+")", t, "sec");
	 					doAdd("sale("+block+","+price+")");
	 				} 
	 			}
	 		}
	 	}
	 }
	 if (message.startsWith("offer") && CS.has("role(consumer)")) {
	 	doForward();
	 }
	 if (message.startsWith("transfer") && CS.has("role(consumer)")) {
	 	String nameTerm = (CS.findT("name(%N)")).toString();
		String name = getContentFromMessage(nameTerm);
		String block = getContentFromMessage(message);
		int index1 = block.indexOf("(");
		int index2 = block.indexOf(",");
		int index3 = block.indexOf(",",index2+1);
		int index4 = block.indexOf(")");
		int f1Sale = Integer.parseInt(block.substring(index1+1,index2));
		int f2Sale = Integer.parseInt(block.substring(index2+1,index3));
		String unitSale = block.substring(index3+1,index4);
		int index5 = block.indexOf("(",index4+1);
		int index6 = block.indexOf(",",index5+1);
		int index7 = block.indexOf(")",index6+1);
		int t1Sale = Integer.parseInt(block.substring(index5+1,index6));
		int t2Sale = Integer.parseInt(block.substring(index6+1,index7));
	 	Term terms = CS.deep_clone();
	  	boolean match = false;
	 	for (int i=0; i < terms.getArity() && !(match); i++) {
	 		if ((terms.get(i)).has("[freq(%F1,%F2,%U),time(%T1,%T2)]")) {
	 			UnifyResult spectrumTerm = (terms.get(i)).find("[freq(%F1,%F2,%U),time(%T1,%T2)]");
	 			int f1 = Integer.parseInt((spectrumTerm.getTVar("%F1")).toString());
	 			int f2 = Integer.parseInt((spectrumTerm.getTVar("%F2")).toString());
	 			String unit = (spectrumTerm.getTVar("%U")).toString();
	 			int t1 = Integer.parseInt((spectrumTerm.getTVar("%T1")).toString());
	 			int t2 = Integer.parseInt((spectrumTerm.getTVar("%T2")).toString());
	 			if (unit.equals(unitSale)) {
	 				if ((f1Sale >= f1) && (f2Sale <= f2) && (t1Sale >= t1) && (t2Sale <= t2) && (CS.has("accessible([freq("+f1+","+f2+","+unit+"),time("+t1+","+t2+")])"))) {
	 					match = true;
	 					doRemove("accessible([freq("+f1+","+f2+","+unit+"),time("+t1+","+t2+")])");
	 					if (f1Sale > f1) {
	 						doAdd("accessible([freq("+f1+","+f1Sale+","+unit+"),time("+t1+","+t2+")])");
	 					}
	 					if (f2Sale < f2) {
	 						doAdd("accessible([freq("+f2Sale+","+f2+","+unit+"),time("+t1+","+t2+")])");
	 					}
	 					if (t1Sale > t1) {
	 						doAdd("accessible([freq("+f1Sale+","+f2Sale+","+unit+"),time("+t1+","+t1Sale+")])");
	 					}
	 					if (t2Sale < t2) {
	 						doAdd("accessible([freq("+f1Sale+","+f2Sale+","+unit+"),time("+t2Sale+","+t2+")])");
	 					}
	 					doForward(source,"transfer("+name+","+block+")",dest); 
	 				}
	 				
	 			}
	 			
	 		}
	 	}
	 }
      }	
      
      public void obligationDue(Term obligationTerm) {
        	if (obligationTerm.toString().startsWith("sale")){
			String saleTerm = (CS.findT("sale(%B,%P)")).toString();
			String content = getContentFromMessage(saleTerm);
			int index = content.indexOf("]");
			String block = content.substring(0,index+1);
			int price = Integer.parseInt(content.substring(index+2,content.length()));
			doRemove(saleTerm);
			doAdd("accessible("+block+")");
			doDeliver(Self,"dealExpired("+block+","+price+")",Self);
		}
        }
      
      
      public void arrived(String source, String message, String dest) {
        String content = getContentFromMessage(message);
        if (message.startsWith("offer")) {
        	int index1 = content.indexOf("]");
	 	int index2 = content.indexOf(",",index1+2);
	 	String block = content.substring(0,index1+1);
	 	int price = Integer.parseInt(content.substring(index1+2,index2));
	 	int card = Integer.parseInt(content.substring(index2+1,content.length()));
	 	if (CS.has("sale("+block+","+price+")")) {
	 		doForward(Self,"requestCreditCheck("+card+","+price+")",bank);	 		
	 		doAdd("pendingOffer("+source+","+content+")");
               	}
        }
        if (message.startsWith("requestCreditCheck") && dest.equals(bank)) {
        	int card = Integer.parseInt(content.substring(0,content.indexOf(",")));
        	doForward(dest,"creditCheckResponse("+card+",approved)",source);
        //	doForward(dest,"creditCheckResponse("+card+",reject)",source);
        	doDeliver();
        }
        if(message.startsWith("creditCheckResponse") && source.equals(bank)) {
        	int card = Integer.parseInt(content.substring(0,content.indexOf(",")));
        	String ans = content.substring(content.indexOf(",")+1,content.length());
        	if ((CS.has("pendingOffer(%X,%B,%P,"+card+")")) && (CS.has("name(%N)"))) {
        		String pendingTerm = (CS.findT("pendingOffer(%X,%B,%P,"+card+")")).toString();
			String pending = getContentFromMessage(pendingTerm);
			int pos1 = pending.indexOf(",");
			String buyer = pending.substring(0,pos1);
			int pos2 = pending.indexOf("]",pos1);
			String block = pending.substring(pos1+1,pos2+1);
			int pos3 = pending.indexOf(",",pos2+2);
			int price = Integer.parseInt(pending.substring(pos2+2,pos3));
			String nameTerm = (CS.findT("name(%N)")).toString();
			String name = getContentFromMessage(nameTerm);
        		if (ans.equals("approved")) {
        			doRepealObligation("sale("+block+","+price+")");
	 			doRemove("sale("+block+","+price+")");
	 			doRemove(pendingTerm);
	 			doForward(dest,"succeeded("+name+","+block+","+price+")",buyer);
	 			doDeliver(Self,"winner("+block+","+price+","+buyer+")",Self);
        		}
        		if (ans.equals("reject")) {
        			doForward(dest,"rejected("+block+","+price+")",buyer);
        			doRemove(pendingTerm);
        		}
        	}
        }
        if ((message.startsWith("succeeded")) && (CS.has("role(consumer)"))) {
        	String block = content.substring(content.indexOf(",")+1,content.indexOf("]")+1);
        	doAdd("accessible("+block+")");
        	String nameTerm = (CS.findT("name(%N)")).toString();
		String name = getContentFromMessage(nameTerm);
        	doForward(dest,"deal("+content+","+name+")",auditor);
        	doDeliver();
        }
        if ((message.startsWith("deal")) && (CS.has("role(auditor)"))) {
		doDeliver();
	}
	if (message.startsWith("rejected")) {
		doDeliver();
	}
	if (message.startsWith("transfer") && CS.has("role(consumer)")) {
		String nameTerm = (CS.findT("name(%N)")).toString();
		String name = getContentFromMessage(nameTerm);
		String block = content.substring(content.indexOf(",")+1,content.length());
		doAdd("accessible("+block+")");
		doForward(dest,"deal("+content+",0,"+name+")",auditor);
		doDeliver();
	}
      }  
        
        
      public void disconnected() {
	doQuit();
      }
      
      
        /**
        Helper method to parse the argument out of a regular expression
    */
    public String getContentFromMessage(String anyMessage) { 

        int index = anyMessage.indexOf("("); 

        if (index == -1) return ""; 
        else return anyMessage.substring(index+1, anyMessage.length()-1); 
    }
}

