
import uk.ac.ic.doc.automed.templates.wrapper.*;
import uk.ac.ic.doc.automed.reps.*;
import uk.ac.ic.doc.automed.wrappers.SQLWrapperFactory;
import uk.ac.ic.doc.automed.InconsistentException;
import uk.ac.ic.doc.automed.IntegrityException;


public class FieldDownHierarchy extends TemplateCompilerSimulator{
  static final Model defaultModel;

  static {
    SQLWrapperFactory swf=new SQLWrapperFactory();

    try {
      swf.setFeatures(2);
    }
    catch (IntegrityException e) {
      throw new InconsistentException("Unable to set features of new wrapper"+
				      " factory",e);
    }

    defaultModel=swf.getAutoMedModel();
  } 

	public FieldDownHierarchy() throws Exception{
		super();
	}

	protected String templateName(){
		return "Parent Field to Specialisations Equivalence (sql_2 model)";
	}

	protected String templateDescription(){
		return "A field is moved from the parent relation to the specialisations";
	}

	protected String defaultModel(){
		return defaultModel.getName();
	}

	protected void defineTemplate() throws Exception{
		Model rel =defaultModel;
		Construct table = rel.getConstruct("table");
		Construct field = rel.getConstruct("column");
//		Construct foreignkey = rel.getConstruct("foreign_key");
		Construct primarykey = rel.getConstruct("primary_key");

		INPUTS();
			OBJECT parentTable = askForObject("Existing parent relation", table);
			//OBJECT parentTable = askForObject("Parent ID field", column);
			OBJECT parentField = askForObject("Field to specialise", field);
			//OBJECTLIST specialisationIDs = askForObject("Specialisation ID fields");
			OBJECTLIST specialisationTables = askForObjectList("Specialisation tables to move field", table);
			
		START();
			FOREACH(); OBJECT specialisationTable = IN (specialisationTables);
				//OBJECT specialisationID = IN(specialisationIDs);
				OBJECT parentTableClone = VARIES_WITH(parentTable);
				OBJECT parentFieldClone = VARIES_WITH(parentField);
			DO();
				ALIAS(specialisationTable, "specialisationTable");
				ALIAS(parentTableClone, "parentTable");
				ALIAS(parentFieldClone, "parentField");

				FUNCTION newFieldExtent = DEFINE_FUNCTION("[ {x,y} | {x}<-@specialisationTable?scheme ; {x1}<-@parentTable?scheme ; {x2,y}<-@parentField?scheme ; (=) x1 x2 ; (=) x x1]");
				NAME newFieldName = DEFINE_NAME("@parentField?name");
				OBJECT newField = ADD( CONSTRUCT.IS(field),
									   SCHEME.IS(new Object[]{specialisationTable, my(newFieldName)}),
									   FUNCTION.IS(newFieldExtent)
								     );

				ALIAS(newField, "newField");
				STRING partialQuery = DEFINE_STRING("[ {x,y} | {x}<-@parentTable?scheme ; {x1,y}<-@newField?scheme  ; (=) x x1]");
				STRINGLIST partialQueriesForParentField = (STRINGLIST) COLLECTS(partialQuery);

			ENDFOREACH();

			STRING query = DEFINE_STRING(partialQueriesForParentField, "++");
			ALIAS(query,"query");
			FUNCTION parentFieldExtent = DEFINE_FUNCTION("@query");
			parentField.DELETE(parentFieldExtent);	
		END();
	}	

	public static void main(String[] args){
		try{
				new FieldDownHierarchy();
		}
		catch(Exception e){
			e.printStackTrace();
		}	

	}

}
