package it.unibz.inf.data_pumper.mappings;

/*
 * #%L
 * dataPumper
 * %%
 * Copyright (C) 2014 Free University of Bozen-Bolzano
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

//import it.unibz.inf.data_pumper.columns.ColumnPumper;
//import it.unibz.inf.data_pumper.connection.DBMSConnection;
//import it.unibz.inf.data_pumper.utils.Template;
//
//import java.sql.PreparedStatement;
//import java.sql.ResultSet;
//import java.sql.SQLException;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
//import org.apache.log4j.Logger;

/**
 * Singleton class
 * @author tir
 *
 */
@Deprecated
public class TuplesPicker {
	
//	private static TuplesPicker picker = null;
//	List<ResultSet> pickFrom;
//	int pickIndex;
//	private TupleTemplate lastTT;
//	private List<String> tableNames;
//	private static final String renamePostfix = "_1";
//	
//	private Map<String, Integer> missedInserts; 
//	
//	
//	private static Logger logger = Logger.getLogger(TuplesPicker.class.getCanonicalName());
//	
//	private TuplesPicker(){
//		pickFrom = new ArrayList<ResultSet>();
//		pickIndex = 0;
//		lastTT = null;
//		tableNames = null;
//		missedInserts = new HashMap<String, Integer>();
//	};
//	
//	static TuplesPicker getInstance(){
//		if( picker == null ){
//			picker = new TuplesPicker();
//		}
//		return picker;
//	}
//	
//	public List<String> pickTuple(DBMSConnection dbToPump, String curTable, TupleTemplate tt){
//		
//		if( this.needsInit(tt) ){
//			
//			this.init(tt);
//		}
//		
//		setValidPickIndex(dbToPump, curTable, tt);
//		
//		if( !(pickIndex < pickFrom.size()) ) return null;
//		
//		// Now, according to the tuple cardinality, pick results from the resultSet
//		ResultSet rs = pickFrom.get(pickIndex);
//		assert rs != null;
//		
//		List<String> tuple = null;
//		
//		try {
//			if( rs.next() ){
//				tuple = new ArrayList<String>();
//				for( int i = 1; i <= tt.getColumnsInTable(curTable).size(); ++i ){
//					if( rs.getString(i) == null ) return null;
//					tuple.add(rs.getString(i));
//				}
//			}
//		} catch (SQLException e) {
//			e.printStackTrace();
//		}
//		
//		// TODO Also, I needed to make the union of the domains, but I forgot
//		//      Because, otherwise, this tuple might be duplicate
//		return tuple;
//	}
//
//	private void init(TupleTemplate tt) {
//		lastTT = tt;
//		tableNames = new ArrayList<String>(tt.getReferredTables());
//		pickFrom = new ArrayList<ResultSet>();
//		for( int i = 0; i < tableNames.size(); ++ i ) pickFrom.add(null);
//	}
//	
//	/**
//	 * To be called each time I end filling a schema
//	 */
//	public void reset(){
//		for( ResultSet rs : pickFrom ){
//			try {
//				if( rs != null ) rs.close();
//			} catch (SQLException e) {
//				e.printStackTrace();
//			}
//		}
//		this.pickFrom.clear();
//		pickIndex = 0;
//		lastTT = null;
//		tableNames = null;
//	}
//
//	private boolean needsInit(TupleTemplate tt) {
//		return !tt.equals(lastTT);
//	}
//	
//	/**
//	 * It finds a suitable <b>pickIndex</b> to pick values
//	 * from the <b>pickFrom</b> resultSet vector
//	 * @param dbToPump
//	 * @param curTable
//	 * @param tt
//	 */
//	private void setValidPickIndex(DBMSConnection dbToPump, String curTable, TupleTemplate tt) {
//		
//		if( !(pickIndex < pickFrom.size()) ) return;
//		
//		try{
//			if( pickFrom.get(pickIndex) != null && !pickFrom.get(pickIndex).isAfterLast()){
//				// You can pick from here
//				return;
//			}
//		}catch(SQLException e){
//			e.printStackTrace();
//		}
//		
//		if( pickFrom.get(pickIndex) == null ){
//			if( createNewResultSet(dbToPump, curTable, tt) )
//				setValidPickIndex(dbToPump, curTable, tt);
//			else{
//				++pickIndex;
//				setValidPickIndex(dbToPump, curTable, tt);
//			}
//		}
//		else{
//			++pickIndex;
//			setValidPickIndex(dbToPump, curTable, tt);
//		}
//	}
//
//	private boolean createNewResultSet(DBMSConnection dbToPump, String curTable, TupleTemplate tt) {
//		
//		String referredTable = tableNames.get(pickIndex);
//		
//		if( referredTable.equals(curTable) ) return false;
//		
//		logger.debug(tt);
//		
//		PreparedStatement stmt = 
//				dbToPump.getPreparedStatement(createTakeTuplesQueryString(dbToPump, curTable, referredTable, tt));
//		
////		ResultSet rs = null;
//		
//		boolean result = false;
//		try( ResultSet rs = stmt.executeQuery() ) {
////		    rs = stmt.executeQuery();
//		    pickFrom.set(pickIndex, rs);
//		    result = !rs.isAfterLast();
//		    logger.debug("isAfterLast????" + !result);
//		} catch (SQLException e) {
//			e.printStackTrace();
//		}		
//		return result;
//	}
//	/**
//	 *   <i>table_a SetMinus table_b</i><br/>
//		 SELECT a.x, a.y
//		 <br />FROM table_a a LEFT JOIN table_b b
//		 ON a.x = b.x AND a.y = b.y
//		 WHERE b.x IS NULL;
//		 <br /><br />
//		 <i>referredTable SetMinus curTable</i><br/>
//		 SELECT refRn.x, refRn.y
//		 <br />FROM referredTable refRn LEFT JOIN curTable curRn
//		 ON refRn.x = curRn.x AND refRn.y = curRn.y
//		 WHERE curRn.x IS NULL;
//	 * @param curTable
//	 * @param referredTable
//	 * @param tt
//	 */
//	private String createTakeTuplesQueryString(DBMSConnection dbToPump, String curTable,
//			String referredTable, TupleTemplate tt) {
//		
//		Template templ = new Template("SELECT ? FROM ? ? LEFT JOIN ? ? ON ? WHERE ? IS NULL LIMIT 300000");
//		
//		templ.setNthPlaceholder(1, projectionList(referredTable, tt));
//		templ.setNthPlaceholder(2, referredTable);
//		templ.setNthPlaceholder(3, rename(referredTable));
//		templ.setNthPlaceholder(4, curTable);
//		templ.setNthPlaceholder(5, rename(curTable));
//		templ.setNthPlaceholder(6, onCondition(dbToPump, curTable, referredTable, tt));
//		templ.setNthPlaceholder(7, lastInOnCondition(curTable, tt));
//		
//		logger.debug(templ.getFilled());
//		
//		return templ.getFilled();
//	}
//
//	private String rename(String tableName){
//		return tableName + renamePostfix;
//	}
//	
//	/**
//	 * WHERE curRn.x IS NULL;
//	 * @param curTable
//	 * @param tt
//	 * @return
//	 */
//	private String lastInOnCondition(String curTable, TupleTemplate tt) {
//		
//		String lastCol = tt.getColumnsInTable(curTable).get(tt.getColumnsInTable(curTable).size()-1);
//		
//		return rename(curTable) + "." + lastCol;
//	}
//
//	/**
//	 * ON refRn.x = curRn.x AND refRn.y = curRn.y
//	 * @param dbToPump 
//	 * @param curTable
//	 * @param referredTable
//	 * @param tt
//	 * @return
//	 */
//	private String onCondition(DBMSConnection dbToPump, String curTable, String referredTable,
//			TupleTemplate tt) {
//		
//		List<String> colsCur = tt.getColumnsInTable(curTable);
//		List<String> colsRef = tt.getColumnsInTable(referredTable);
//		
//		assert colsCur.size() == colsRef.size();
//		
//		List<String> pkNames = new ArrayList<String>();
//		
//		// If the tuple strictly subsumes a pk, then the join ON clause 
//		// has to involve columns in that pk ONLY
//		for( ColumnPumper cP : dbToPump.getSchema(curTable).getPk() ){
//			pkNames.add(cP.getName());
//		}
//		
//		StringBuilder builder = new StringBuilder();
//		if( colsCur.containsAll(pkNames) ){
//			
//			for( int i = 0; i < pkNames.size(); ++i ){
//				if( !(i == 0) ){
//					builder.append(" AND ");
//				}
//				builder.append(rename(referredTable) + "." + pkNames.get(i));
//				builder.append("=");
//				builder.append( rename(curTable) + "." + pkNames.get(i) );
//			}
//		}
//		else{
//			for( int i = 0; i < colsCur.size(); ++i ){
//				if( !(i == 0) ){
//					builder.append(" AND ");
//				}
//				builder.append(rename(referredTable) + "." + colsCur.get(i));
//				builder.append("=");
//				builder.append( rename(curTable) + "." + colsCur.get(i) );
//			}
//		}
//		
//		logger.debug("ON CLAUSE: " + builder.toString());
//		
//		return builder.toString();
//	}
//
//	/**
//	 * SELECT refRn.x, curRn.y
//	 * @param curTable
//	 * @param referredTable
//	 * @param tt
//	 * @return
//	 */
//	private String projectionList(String referredTable,
//			TupleTemplate tt) {
//		
//		List<String> cols = tt.getColumnsInTable(referredTable);
//		
//		StringBuilder builder = new StringBuilder();
//		
//		for( String col : cols ){
//			if( !(builder.length() == 0) ){
//				builder.append(", ");
//			}
//			builder.append(rename(referredTable) + "." + col);
//		}
//		
//		logger.debug("PROJ:" + builder.toString());
//		
//		return builder.toString();
//	}
//
//	public void setMissedInserts(TupleTemplateDecorator candidate, int nMissed) {
//		TupleStore tS = TupleStoreFactory.getInstance().getTupleStoreInstance();
//		missedInserts.put(tS.getTupleOfID(candidate.belongsToTuple()) + "_" + candidate.getTemplatesString(), nMissed);
//	}
//	
};