import java.sql.*;
import java.io.*;
import uk.ac.ic.doc.automed.*;
import uk.ac.ic.doc.automed.reps.*;
import uk.ac.ic.doc.automed.wrappers.*;
import java.util.ArrayList;

/*
 * A few methods used by the AutoMed example applications.
 */
public class AutoMedUtils {
  static int debug=0;

  public static boolean checkAndIntegrateSchemas(Schema s1,Schema s2) {
    SchemaObject[] aLessB=s1.differenceByName(s2);
    SchemaObject[] bLessA=s2.differenceByName(s1);
    boolean integrationOK=true;

    if (aLessB.length>0) {
      System.out.println(s1.getName()+"-"+s2.getName()+"=");
      for (int i=0;i<aLessB.length;i++)
	System.out.println("  "+aLessB[i]);
      integrationOK=false;
    }
	  
    if (bLessA.length>0) {
      System.out.println(s2.getName()+"-"+s1.getName()+"=");
      for (int i=0;i<bLessA.length;i++)
	System.out.println("  "+bLessA[i]);
      integrationOK=false;
    }

    if (integrationOK) {	
      try {
	Transformation.createIdentTransformation(s1,s2,null,null);
	System.out.println("Integration of "+s1.getName()+" and "+
			   s2.getName()+" succeeded");
      }
      catch (SchemasNotIdenticalException e) {
	throw new InconsistentException("Ident of identical schemas failed",e);
      }

      return true;
    }

    return false;
  }

  /** This should be a fairly standard check in an AutoMed application
   *  to see if two schemas can be "integrated" via an ID
   *  transformation.  */
  public static void integrateSchemas(Schema s1,Schema s2) {
    boolean integrationOK=true;
    
    System.out.print("Integration of "+s1.getName()+" and "+
		     s2.getName());

    try {
      Transformation.createIdentTransformation(s1,s2,null,null);
      System.out.println(" succeeded");
    }
    catch (SchemasNotIdenticalException e) {
      System.out.println(" failed");
      
      System.out.print("*** Schema " + e.getFromSchema().getName());
      System.out.println("has following SchemaObjects not matched");
      SchemaObject[] fromSo=e.getFromObjectsUnmatched();
      for (int i=0; i<fromSo.length; i++)
	System.out.println(fromSo[i]);
      
      System.out.print("*** Schema " + e.getToSchema().getName());
      System.out.println("has following SchemaObjects not matched");
      SchemaObject[] toSo=e.getToObjectsUnmatched();
      for (int i=0; i<toSo.length; i++)
	System.out.println(toSo[i]);
    }
  }
  
  public static void banner(String title) {
    int len=title.length();
    String stars="*******************************************************************************";
    int slen=stars.length();

    System.out.println(stars);
    if (len>slen-4)
      System.out.println(title);
    else 
      System.out.println(stars.substring(0,(slen-len)/2-1)+" "+title+
			 (len%2==0 ? " " : "  ")+
			 stars.substring(0,(slen-len)/2));      
    System.out.println(stars);
  }

  public static void banner(Schema s) {
    banner(s.getName());
  }

  private static boolean bombOut=false;

  public static Schema wrapSchema(String username,String password,
					 String driver,String urlbase,
					 SQLWrapperFactory wf,
					 String db,String name) 
  throws Exception {
    // Ensure we are clear of all the schemas we are to create
    String sourceName=name+"_src";
    if (Schema.exists(name))
      Schema.getSchema(name).retract();
    if (Schema.exists(sourceName))
      Schema.getSchema(sourceName).retract();

    // Get the Source oriented schema
    AutoMedWrapper sw=
      AutoMedWrapper.selectNewAutoMedWrapper(username,password,null,driver,
					     urlbase+db,sourceName,wf);
    Schema sourceSchema=sw.getSchema();
    banner(sourceSchema);
    sourceSchema.listSchema();

    // Generate an AutoMed oriented schema
    Schema s=sw.newAutoMedSchema(name);
    banner(s);
    s.listSchema();    
    
    return s;
  }
}
