package com.xtremelabs.robolectric.shadows;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.*;
import com.xtremelabs.robolectric.Robolectric;
import com.xtremelabs.robolectric.internal.Implementation;
import com.xtremelabs.robolectric.internal.Implements;
import com.xtremelabs.robolectric.internal.RealObject;
import com.xtremelabs.robolectric.util.DatabaseConfig;
import com.xtremelabs.robolectric.util.SQLite.SQLStringAndBindings;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.WeakHashMap;
import java.util.concurrent.locks.ReentrantLock;

import static com.xtremelabs.robolectric.Robolectric.newInstanceOf;
import static com.xtremelabs.robolectric.Robolectric.shadowOf;
import static com.xtremelabs.robolectric.util.SQLite.buildDeleteString;
import static com.xtremelabs.robolectric.util.SQLite.buildInsertString;
import static com.xtremelabs.robolectric.util.SQLite.buildUpdateString;
import static com.xtremelabs.robolectric.util.SQLite.buildWhereClause;

/**
 * Shadow for {@code SQLiteDatabase} that simulates the movement of a {@code Cursor} through database tables.
 * Implemented as a wrapper around an embedded SQL database, accessed via JDBC.  The JDBC connection is
 * made available to test cases for use in fixture setup and assertions.
 */
@Implements(SQLiteDatabase.class)
public class ShadowSQLiteDatabase  {
	@RealObject	SQLiteDatabase realSQLiteDatabase;
    private static Connection connection;
    private final ReentrantLock mLock = new ReentrantLock(true);
    private boolean mLockingEnabled = true;
    private WeakHashMap<SQLiteClosable, Object> mPrograms;
    private boolean inTransaction = false;
    private boolean transactionSuccess = false;
    private boolean throwOnInsert;
    
    @Implementation
    public void setLockingEnabled(boolean lockingEnabled) {
        mLockingEnabled = lockingEnabled;
    }
    
    public void lock() {
        if (!mLockingEnabled) return;
        mLock.lock();
    }
    
    public void unlock() {
        if (!mLockingEnabled) return;
        mLock.unlock();
    }
    
    public void setThrowOnInsert(boolean throwOnInsert) {
        this.throwOnInsert = throwOnInsert;
    }
    
    @Implementation
    public static SQLiteDatabase openDatabase(String path, SQLiteDatabase.CursorFactory factory, int flags) {
     	connection = DatabaseConfig.getMemoryConnection();
        return newInstanceOf(SQLiteDatabase.class);
    }
    
    @Implementation
    public long insert(String table, String nullColumnHack, ContentValues values) {
        return insertWithOnConflict(table, nullColumnHack, values, SQLiteDatabase.CONFLICT_NONE);
    }
    
    @Implementation
    public long insertOrThrow(String table, String nullColumnHack, ContentValues values) {
        if (throwOnInsert)
            throw new android.database.SQLException();
        return insertWithOnConflict(table, nullColumnHack, values, SQLiteDatabase.CONFLICT_NONE);
    }

    @Implementation
    public long replace(String table, String nullColumnHack, ContentValues values) {
        return insertWithOnConflict(table, nullColumnHack, values, SQLiteDatabase.CONFLICT_REPLACE);
    }

    @Implementation
    public long insertWithOnConflict(String table, String nullColumnHack,
            ContentValues initialValues, int conflictAlgorithm) {

        try {
            SQLStringAndBindings sqlInsertString = buildInsertString(table, initialValues, conflictAlgorithm);
            PreparedStatement insert = connection.prepareStatement(sqlInsertString.sql, Statement.RETURN_GENERATED_KEYS);
            Iterator<Object> columns = sqlInsertString.columnValues.iterator();
            int i = 1;
            long result = -1;
            while (columns.hasNext()) {
                insert.setObject(i++, columns.next());
            }
            insert.executeUpdate();
            ResultSet resultSet = insert.getGeneratedKeys();
            if (resultSet.next()) {
                result = resultSet.getLong(1);
            }
            resultSet.close();
            return result;
        } catch (SQLException e) {
            return -1; // this is how SQLite behaves, unlike H2 which throws exceptions
        }
    }

    @Implementation
    public Cursor query(boolean distinct, String table, String[] columns,
                        String selection, String[] selectionArgs, String groupBy,
                        String having, String orderBy, String limit) {

        String where = selection;
        if (selection != null && selectionArgs != null) {
            where = buildWhereClause(selection, selectionArgs);
        }

        String sql = SQLiteQueryBuilder.buildQueryString(distinct, table,
                columns, where, groupBy, having, orderBy, limit);

        ResultSet resultSet;
        try {
            Statement statement = connection.createStatement(DatabaseConfig.getResultSetType(), ResultSet.CONCUR_READ_ONLY);
            resultSet = statement.executeQuery(sql);
        } catch (SQLException e) {
            throw new RuntimeException("SQL exception in query", e);
        }

        SQLiteCursor cursor = new SQLiteCursor(null, null, null, null);
        shadowOf(cursor).setResultSet(resultSet,sql);
        return cursor;
    }

    @Implementation
    public Cursor query(String table, String[] columns, String selection,
                        String[] selectionArgs, String groupBy, String having,
                        String orderBy) {
        return query(false, table, columns, selection, selectionArgs, groupBy, having, orderBy, null);
    }

    @Implementation
    public Cursor query(String table, String[] columns, String selection,
                        String[] selectionArgs, String groupBy, String having,
                        String orderBy, String limit) {
        return query(false, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
    }

    @Implementation
    public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
        SQLStringAndBindings sqlUpdateString = buildUpdateString(table, values, whereClause, whereArgs);

        try {
            PreparedStatement statement = connection.prepareStatement(sqlUpdateString.sql);
            Iterator<Object> columns = sqlUpdateString.columnValues.iterator();
            int i = 1;
            while (columns.hasNext()) {
                statement.setObject(i++, columns.next());
            }

            return statement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("SQL exception in update", e);
        }
    }

    @Implementation
    public int delete(String table, String whereClause, String[] whereArgs) {
        String sql = buildDeleteString(table, whereClause, whereArgs);

        try {
            return connection.prepareStatement(sql).executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("SQL exception in delete", e);
        }
    }

    @Implementation
    public void execSQL(String sql) throws android.database.SQLException {
        if (!isOpen()) {
            throw new IllegalStateException("database not open");
        }

        try {
        	String scrubbedSql= DatabaseConfig.getScrubSQL(sql);
            connection.createStatement().execute(scrubbedSql);
        } catch (java.sql.SQLException e) {
            android.database.SQLException ase = new android.database.SQLException();
            ase.initCause(e);
            throw ase;
        }
    }

    @Implementation
    public void execSQL(String sql, Object[] bindArgs) throws SQLException {
        if (bindArgs == null) {
            throw new IllegalArgumentException("Empty bindArgs");
        }
        String scrubbedSql= DatabaseConfig.getScrubSQL(sql);
        
        
        SQLiteStatement statement = null;
        	try {
        		statement =compileStatement(scrubbedSql);
            if (bindArgs != null) {
                int numArgs = bindArgs.length;
                for (int i = 0; i < numArgs; i++) {
                    DatabaseUtils.bindObjectToProgram(statement, i + 1, bindArgs[i]);
                }
            }
            statement.execute();
        } catch (SQLiteDatabaseCorruptException e) {
            throw e;
        } finally {
            if (statement != null) {
                statement.close();
            }
        }
    }


    @Implementation
    public Cursor rawQuery (String sql, String[] selectionArgs) {
    	return rawQueryWithFactory( new SQLiteDatabase.CursorFactory() {
			@Override
			public Cursor newCursor(SQLiteDatabase db,
					SQLiteCursorDriver masterQuery, String editTable, SQLiteQuery query) {
				return new SQLiteCursor(db, masterQuery, editTable, query);
			}
    		
    	}, sql, selectionArgs, null );
    }
    
    @Implementation
    public Cursor rawQueryWithFactory (SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable) {
       	String sqlBody = sql;
        if (sql != null) {
        	sqlBody = buildWhereClause(sql, selectionArgs);
        }
    	
        ResultSet resultSet;
        try {
          	SQLiteStatement stmt = compileStatement(sql);
          	
          	 int numArgs = selectionArgs == null ? 0
                     : selectionArgs.length;
             for (int i = 0; i < numArgs; i++) {
            		stmt.bindString(i + 1, selectionArgs[i]);
             }
          
              resultSet = Robolectric.shadowOf(stmt).getStatement().executeQuery();
          } catch (SQLException e) {
              throw new RuntimeException("SQL exception in query", e);
          }
          //TODO: assert rawquery with args returns actual values
          
        SQLiteCursor cursor = (SQLiteCursor) cursorFactory.newCursor(null, null, null, null);
        shadowOf(cursor).setResultSet(resultSet, sqlBody);
        return cursor;
    }
    
    @Implementation
    public boolean isOpen() {
        return (connection != null);
    }

    @Implementation
    public void close() {
        if (!isOpen()) {
            return;
        }
        try {
            connection.close();
            connection = null;
        } catch (SQLException e) {
            throw new RuntimeException("SQL exception in close", e);
        }
    }

	@Implementation
	public void beginTransaction() {
		try {
			connection.setAutoCommit(false);
		} catch (SQLException e) {
			throw new RuntimeException("SQL exception in beginTransaction", e);
		} finally {
			inTransaction = true;
		}
	}

	@Implementation
	public void setTransactionSuccessful() {
		if (!isOpen()) {
			throw new IllegalStateException("connection is not opened");
		} else if (transactionSuccess) {
			throw new IllegalStateException("transaction already successfully");
		}
		transactionSuccess = true;
	}

	@Implementation
	public void endTransaction() {
		try {
			if (transactionSuccess) {
				transactionSuccess = false;
				connection.commit();
			} else {
				connection.rollback();
			}
			connection.setAutoCommit(true);
		} catch (SQLException e) {
			throw new RuntimeException("SQL exception in beginTransaction", e);
		} finally {
			inTransaction = false;
		}
	}
	
	@Implementation
	public boolean inTransaction() {
		return inTransaction;
	}
	
	/**
	 * Allows tests cases to query the transaction state
	 * @return
	 */
	public boolean isTransactionSuccess() { 
		return transactionSuccess; 
	}

    /**
     * Allows test cases access to the underlying JDBC connection, for use in
     * setup or assertions.
     *
     * @return the connection
     */
    public Connection getConnection() {
        return connection;
    }
    
    @Implementation
    public SQLiteStatement compileStatement(String sql) throws SQLException {
        lock();
        String scrubbedSql= DatabaseConfig.getScrubSQL(sql);
        try {
        	SQLiteStatement stmt = Robolectric.newInstanceOf(SQLiteStatement.class);
        	Robolectric.shadowOf(stmt).init(realSQLiteDatabase, scrubbedSql);
            return stmt;
        } catch (Exception e){
        	throw new RuntimeException(e);
        } finally {
            unlock();
        }
    }
    
	   /**
     * @param closable
     */
    void addSQLiteClosable(SQLiteClosable closable) {
        lock();
        try {
            mPrograms.put(closable, null);
        } finally {
            unlock();
        }
    }

    void removeSQLiteClosable(SQLiteClosable closable) {
        lock();
        try {
            mPrograms.remove(closable);
        } finally {
            unlock();
        }
    }  
    
}
