package test;

import java.util.Iterator;
import uk.ac.bbk.dcs.automed.qproc.iql.ASG;
import uk.ac.ic.doc.automed.AutoMedException;
import uk.ac.ic.doc.automed.util.Debugger;
import uk.ac.ic.doc.automed.util.LogOutputHandler;
import uk.ac.ic.doc.automed.util.Logger;
import uk.ac.ic.doc.rodex.qproc.QueryAnalyser;
import uk.ac.ic.doc.rodex.qproc.QueryIntegrityException;
import uk.ac.ic.doc.rodex.qproc.QueryRewriteProcessor;
import uk.ac.ic.doc.rodex.qproc.QueryRewriterException;
import uk.ac.ic.doc.rodex.qproc.QueryRewriterResult;


/**
 * TestMiniCon.java<br><br>
 *
 *
 *
 * @author Duc M Le  <a href="mailto:dmle@doc.ic.ac.uk"><i>dmle@doc.ic.ac.uk</i></a>
 * <br>Created on August 19, 2006
 * <br>Department of Computing, Imperial College
 */

public class TestMiniCon {
  
  /**
   * Creates a new instance of TestMiniCon
   */
  public TestMiniCon() {
  }
  
  public static void main(String[] args) throws Exception {
    Debugger.setSectionDebugLevel(Debugger.DEBUG_GENERAL, Debugger.DEBUG_LEVEL_ERROR);
    Debugger.setSectionDebugLevel(Debugger.DEBUG_QUERY_REWRITE, Debugger.DEBUG_LEVEL_DETAILED);
    Logger.setOutputHandler(new LogOutputHandler(
      LogOutputHandler.CONSOLE + LogOutputHandler.FILE));
    
    QueryRewriterResult rwResult = null;
    String query1 = "[{x ,y }|{r ,x }<-<<person,id>> ; {r ,y }<-<<person,yob>> ; x = 1]";
    String query2 = "[{x ,y }|{r ,x }<-<<person,id>> ; {r ,y }<-<<person,yob>> ; x = 1; y >= 1975]";
    String query3 = "[{x ,y }|{r ,x }<-<<person,id>> ; {r ,y }<-<<person,yob>> ; y = 1976; x = 1]";
    String query4 = "[{x ,y }|{r ,x }<-<<person,id>> ; {r ,y }<-<<person,yob>> ; y = 1976; x > 1]";
    // query5: shows no results although it should!!!!
    // --> this means that before passing a query to MiniCon rewriter, it must
    // have first been 'reformulated' so that to reduce/summarise all the predicates    
    String query5 = "[{x ,y }|{r ,x }<-<<person,id>> ; {r ,y }<-<<person,yob>> ; y = 1976; y >=1977]";
    
    String query6 = "[{y }| {r ,y }<-<<person,yob>> ; y > 1971; y < 1976]";

    String query7 = "[{y,n} | {r ,y }<-<<person,yob>> ; {r ,n}<-<<person,fullname>>]";

    String query8 = "[{y,n} | {r ,y }<-<<person,yob>> ; {r ,n}<-<<person,fullname>>; y > 1971; y <= 1975; n = 'Duc']";

    
    String query9 = "[{y,n,s} | {r ,y }<-<<person,yob>> ;{r,s}<-<<person,ssn>>; {r ,n}<-<<person,fullname>>; {r,x}<-<<person,x>>;" +
      "y > 1971; y <= 1975; n > 'A'; n <= 'D']";
    
    // <<person,dept>> is found b/c variable d is not in the head
    String query10 = "[{y,n,dn} | {r ,y }<-<<person,yob>> ;{r,d}<-<<person,dept>>;{r2,d}<-<<dept,id>>;{r2,dn}<-<<dept,dname>>; " +
      "{r ,n}<-<<person,fullname>>]";

    // <<person,dept>> is found b/c variable d is in the head
    String query11 = "[{y,n,d} | {r ,y }<-<<person,yob>> ;{r,d}<-<<person,dept>>;{r2,d}<-<<dept,id>>; " +
      "{r ,n}<-<<person,fullname>>]";

    String query = query11;
    
    String[] views = new String[] {
      "[{a1 ,b1 ,c1 }|{t ,a1 }<-<<person,id>> ; {t ,b1 }<-<<person,name>> ; " +
        "{t ,c1 }<-<<person,yob>> ; ( (=) a1 1 ) ; ( (=) c1 1975 ) ]",
      "[{a ,b ,c }|{t ,a }<-<<person,id>> ; {t ,b }<-<<person,name>> ; " +
        "{t ,c }<-<<person,yob>> ; ( (=) a 2 ) ; ( (=) c 1974 ) ]",
      "[{a2 ,b2 ,c2 }|{t ,a2 }<-<<person,id>> ; {t ,b2 }<-<<person,name>> ; " +
        "{t ,c2 }<-<<person,yob>> ; ( (=) a2 3 ) ; ( (=) c2 1976 ) ]",
      "[{a3 ,b3 ,c3 }|{t ,a3 }<-<<person,id>> ; {t ,b3 }<-<<person,name>> ; " +
        "{t ,c3 }<-<<person,yob>> ; ( (=) a3 4 ) ; ( (=) c3 1977 ) ]",
      "[{a4 ,b4 ,c4 }|{t ,a4 }<-<<person,id>> ; {t ,b4 }<-<<person,name>> ; " +
        "{t ,c4 }<-<<person,yob>> ; ( (=) a4 5 ) ; ( (=) c4 1978 ) ]",
      "[{a5 ,b5 ,c5 }|{t ,a5 }<-<<person,id>> ; {t ,b5 }<-<<person,name>> ; " +
        "{t ,c5 }<-<<person,yob>> ; ( (=) a5 6 ) ; ( (<) c5 1980 ); ( (>) c5 1977 ) ]",
      "[{dx}|{r ,dx }<-<<person,dept>>]",
//      "[{i}|{r ,i }<-<<dept,id>>]",
//      "[{dx,i}|{r ,dx }<-<<person,dept>>;{r ,i }<-<<dept,id>>]",
    };
    //String tuple = "[{4 ,'person_4' ,1974 }] ]";
    
    try {
//      QueryRewriteProcessor qp = new QueryRewriteProcessor(null, new ASG(query), QueryRewriteProcessor.TYPE_MINICON);
//      QueryRewriteProcessor qp = new QueryRewriteProcessor(null, new ASG(query), QueryRewriteProcessor.TYPE_MINICON_NONCONJUNCTIVE);
      QueryRewriteProcessor qp = new QueryRewriteProcessor(null, new ASG(query), QueryRewriteProcessor.TYPE_MINICON_ADAPTIVE);
      
      QueryAnalyser[] qas = new QueryAnalyser[views.length];
      for (int i =0;i<views.length;i++) {
        QueryAnalyser qa = new QueryAnalyser(new ASG(views[i]));
        qa.analyse();
        qas[i] = qa;
      }
      qp.initRewriterEngine(qas);
      rwResult = qp.rewrite();
    } catch (QueryIntegrityException ex) {
      Logger.error("", "", ex.getMessage(), ex);
    } catch (QueryRewriterException ex) {
      Logger.error("", "", ex.getMessage(), ex);
    } catch (AutoMedException ex) {
      Logger.error("", "", ex.getMessage(), ex);
    }
    
    StringBuffer sb = new StringBuffer("################################################\n");
    
    sb.append("Query: " + query);
    sb.append("\nCached views: \n");
    if (rwResult != null) {      
      for (int i = 0; i < rwResult.length(); i++) {
        java.util.List viewSet = rwResult.getViewSet(i);
        sb.append("cached view set: " + i + "\n");
        for (Iterator vsIt = viewSet.iterator(); vsIt.hasNext();) {
          ASG view = (ASG) vsIt.next();
          sb.append("\t" + view + "\n");
        }
      }
      
      // remainder query
      sb.append("\nContainment query:").append(rwResult.getContainmentQuery());
      sb.append("\nRemainder query:").append(rwResult.getRemainderQuery());
      sb.append("\nOutput query:").append(rwResult.createOutputQuery());
      
    } else {
      sb.append("Not found!");
    }
    
    
    Logger.debug("","",sb.toString(),Debugger.DEBUG_QUERY_REWRITE, Debugger.DEBUG_LEVEL_NONE);
  }
}
