/**
 * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.emf.cdo.server.internal.db;

import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea.Handler;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaAlreadyExistsException;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaNotFoundException;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IIDHandler;
import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;

import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBType;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBIndex;
import org.eclipse.net4j.db.ddl.IDBSchema;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.lifecycle.Lifecycle;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author Eike Stepper
 */
public class DurableLockingManager extends Lifecycle
{
  private DBStore store;

  private InternalCDOBranchManager branchManager;

  private IIDHandler idHandler;

  private IDBTable lockAreas;

  private IDBField lockAreasID;

  private IDBField lockAreasUser;

  private IDBField lockAreasBranch;

  private IDBField lockAreasTime;

  private IDBField lockAreasReadOnly;

  private IDBTable locks;

  private IDBField locksArea;

  private IDBField locksObject;

  private IDBField locksGrade;

  private String sqlInsertLockArea;

  private String sqlSelectLockArea;

  private String sqlSelectAllLockAreas;

  private String sqlSelectLockAreas;

  private String sqlDeleteLockArea;

  private String sqlSelectLocks;

  private String sqlSelectLock;

  private String sqlInsertLock;

  private String sqlUpdateLock;

  private String sqlDeleteLock;

  private String sqlDeleteLocks;

  public DurableLockingManager(DBStore store)
  {
    this.store = store;
  }

  public synchronized LockArea createLockArea(DBStoreAccessor accessor, String durableLockingID, String userID,
      CDOBranchPoint branchPoint, boolean readOnly, Map<CDOID, LockGrade> locks)
  {
    try
    {
      if (durableLockingID == null)
      {
        durableLockingID = getNextDurableLockingID(accessor);
      }
      else
      {
        // If the caller is specifying the ID, make sure there is no area with this ID yet
        //
        try
        {
          getLockArea(accessor, durableLockingID);
          throw new LockAreaAlreadyExistsException(durableLockingID);
        }
        catch (LockAreaNotFoundException good)
        {
        }
      }

      IPreparedStatementCache statementCache = accessor.getStatementCache();
      PreparedStatement stmt = null;

      try
      {
        stmt = statementCache.getPreparedStatement(sqlInsertLockArea, ReuseProbability.LOW);
        stmt.setString(1, durableLockingID);
        stmt.setString(2, userID);
        stmt.setInt(3, branchPoint.getBranch().getID());
        stmt.setLong(4, branchPoint.getTimeStamp());
        stmt.setBoolean(5, readOnly);

        DBUtil.update(stmt, true);
      }
      catch (SQLException e)
      {
        throw new DBException(e);
      }
      finally
      {
        statementCache.releasePreparedStatement(stmt);
      }

      if (!locks.isEmpty())
      {
        insertLocks(accessor, durableLockingID, locks);
      }

      accessor.getConnection().commit();

      return CDOLockUtil.createLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
    }
    catch (SQLException ex)
    {
      throw new DBException(ex);
    }
  }

  private void insertLocks(DBStoreAccessor accessor, String durableLockingID, Map<CDOID, LockGrade> locks)
  {
    IPreparedStatementCache statementCache = accessor.getStatementCache();
    PreparedStatement stmt = null;

    try
    {
      stmt = statementCache.getPreparedStatement(sqlInsertLock, ReuseProbability.MEDIUM);
      stmt.setString(1, durableLockingID);

      for (Entry<CDOID, LockGrade> entry : locks.entrySet())
      {
        CDOID id = entry.getKey();
        int grade = entry.getValue().getValue();

        idHandler.setCDOID(stmt, 2, id);
        stmt.setInt(3, grade);

        DBUtil.update(stmt, true);
      }
    }
    catch (SQLException e)
    {
      throw new DBException(e);
    }
    finally
    {
      statementCache.releasePreparedStatement(stmt);
    }
  }

  public LockArea getLockArea(DBStoreAccessor accessor, String durableLockingID) throws LockAreaNotFoundException
  {
    IPreparedStatementCache statementCache = accessor.getStatementCache();
    PreparedStatement stmt = null;
    ResultSet resultSet = null;

    try
    {
      stmt = statementCache.getPreparedStatement(sqlSelectLockArea, ReuseProbability.MEDIUM);
      stmt.setString(1, durableLockingID);
      resultSet = stmt.executeQuery();

      if (!resultSet.next())
      {
        throw new LockAreaNotFoundException(durableLockingID);
      }

      String userID = resultSet.getString(1);
      int branchID = resultSet.getInt(2);
      long timeStamp = resultSet.getLong(3);
      boolean readOnly = resultSet.getBoolean(4);

      return makeLockArea(accessor, durableLockingID, userID, branchID, timeStamp, readOnly);
    }
    catch (SQLException e)
    {
      throw new DBException(e);
    }
    finally
    {
      DBUtil.close(resultSet);
      statementCache.releasePreparedStatement(stmt);
    }
  }

  public void getLockAreas(DBStoreAccessor accessor, String userIDPrefix, Handler handler)
  {
    IPreparedStatementCache statementCache = accessor.getStatementCache();
    PreparedStatement stmt = null;
    ResultSet resultSet = null;

    try
    {
      if (userIDPrefix.length() == 0)
      {
        stmt = statementCache.getPreparedStatement(sqlSelectAllLockAreas, ReuseProbability.MEDIUM);
      }
      else
      {
        stmt = statementCache.getPreparedStatement(sqlSelectLockAreas, ReuseProbability.MEDIUM);
        stmt.setString(1, userIDPrefix + "%");
      }

      resultSet = stmt.executeQuery();
      while (resultSet.next())
      {
        String durableLockingID = resultSet.getString(1);
        String userID = resultSet.getString(2);
        int branchID = resultSet.getInt(3);
        long timeStamp = resultSet.getLong(4);
        boolean readOnly = resultSet.getBoolean(5);

        LockArea area = makeLockArea(accessor, durableLockingID, userID, branchID, timeStamp, readOnly);
        if (!handler.handleLockArea(area))
        {
          break;
        }
      }
    }
    catch (SQLException e)
    {
      throw new DBException(e);
    }
    finally
    {
      DBUtil.close(resultSet);
      statementCache.releasePreparedStatement(stmt);
    }
  }

  public void deleteLockArea(DBStoreAccessor accessor, String durableLockingID)
  {
    try
    {
      unlockWithoutCommit(accessor, durableLockingID);

      IPreparedStatementCache statementCache = accessor.getStatementCache();
      PreparedStatement stmt = null;

      try
      {
        stmt = statementCache.getPreparedStatement(sqlDeleteLockArea, ReuseProbability.LOW);
        stmt.setString(1, durableLockingID);

        DBUtil.update(stmt, true);
      }
      catch (SQLException e)
      {
        throw new DBException(e);
      }
      finally
      {
        statementCache.releasePreparedStatement(stmt);
      }

      accessor.getConnection().commit();
    }
    catch (SQLException e)
    {
      throw new DBException(e);
    }
  }

  public void updateLockArea(DBStoreAccessor accessor, LockArea area)
  {
    try
    {
      String areaID = area.getDurableLockingID();
      unlockWithoutCommit(accessor, areaID);
      insertLocks(accessor, areaID, area.getLocks());

      accessor.getConnection().commit();
    }
    catch (SQLException e)
    {
      throw new DBException(e);
    }
  }

  public void lock(DBStoreAccessor accessor, String durableLockingID, LockType type,
      Collection<? extends Object> objectsToLock)
  {
    changeLocks(accessor, durableLockingID, type, objectsToLock, true);
  }

  public void unlock(DBStoreAccessor accessor, String durableLockingID, LockType type,
      Collection<? extends Object> objectsToUnlock)
  {
    changeLocks(accessor, durableLockingID, type, objectsToUnlock, false);
  }

  public void unlock(DBStoreAccessor accessor, String durableLockingID)
  {
    try
    {
      unlockWithoutCommit(accessor, durableLockingID);
      accessor.getConnection().commit();
    }
    catch (SQLException e)
    {
      throw new DBException(e);
    }
  }

  private void unlockWithoutCommit(DBStoreAccessor accessor, String durableLockingID)
  {
    IPreparedStatementCache statementCache = accessor.getStatementCache();
    PreparedStatement stmt = null;

    try
    {
      stmt = statementCache.getPreparedStatement(sqlDeleteLocks, ReuseProbability.MEDIUM);
      stmt.setString(1, durableLockingID);

      DBUtil.update(stmt, false);
    }
    catch (SQLException e)
    {
      throw new DBException(e);
    }
    finally
    {
      statementCache.releasePreparedStatement(stmt);
    }
  }

  @Override
  protected void doActivate() throws Exception
  {
    super.doActivate();

    branchManager = store.getRepository().getBranchManager();
    idHandler = store.getIDHandler();

    IDBSchema schema = store.getDBSchema();

    // Lock areas
    lockAreas = schema.addTable("cdo_lock_areas");
    lockAreasID = lockAreas.addField("id", DBType.VARCHAR);
    lockAreasUser = lockAreas.addField("user_id", DBType.VARCHAR);
    lockAreasBranch = lockAreas.addField("view_branch", DBType.INTEGER);
    lockAreasTime = lockAreas.addField("view_time", DBType.BIGINT);
    lockAreasReadOnly = lockAreas.addField("read_only", DBType.BOOLEAN);

    lockAreas.addIndex(IDBIndex.Type.PRIMARY_KEY, lockAreasID);
    lockAreas.addIndex(IDBIndex.Type.NON_UNIQUE, lockAreasUser);

    // Locks
    locks = schema.addTable("cdo_locks");
    locksArea = locks.addField("area_id", DBType.VARCHAR);
    locksObject = locks.addField("object_id", idHandler.getDBType());
    locksGrade = locks.addField("lock_grade", DBType.INTEGER);

    locks.addIndex(IDBIndex.Type.PRIMARY_KEY, locksArea, locksObject);
    locks.addIndex(IDBIndex.Type.NON_UNIQUE, locksArea);

    IDBStoreAccessor writer = store.getWriter(null);
    Connection connection = writer.getConnection();
    Statement statement = null;

    try
    {
      statement = connection.createStatement();
      store.getDBAdapter().createTable(lockAreas, statement);
      store.getDBAdapter().createTable(locks, statement);
      connection.commit();
    }
    catch (SQLException ex)
    {
      connection.rollback();
      throw new DBException(ex);
    }
    finally
    {
      DBUtil.close(statement);
      writer.release();
    }

    StringBuilder builder = new StringBuilder();
    builder.append("INSERT INTO "); //$NON-NLS-1$
    builder.append(lockAreas);
    builder.append("("); //$NON-NLS-1$
    builder.append(lockAreasID);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasUser);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasBranch);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasTime);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasReadOnly);
    builder.append(") VALUES (?, ?, ?, ?, ?)"); //$NON-NLS-1$
    sqlInsertLockArea = builder.toString();

    builder = new StringBuilder();
    builder.append("SELECT "); //$NON-NLS-1$
    builder.append(lockAreasUser);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasBranch);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasTime);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasReadOnly);
    builder.append(" FROM "); //$NON-NLS-1$
    builder.append(lockAreas);
    builder.append(" WHERE "); //$NON-NLS-1$
    builder.append(lockAreasID);
    builder.append("=?"); //$NON-NLS-1$
    sqlSelectLockArea = builder.toString();

    builder = new StringBuilder();
    builder.append("SELECT "); //$NON-NLS-1$
    builder.append(lockAreasID);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasUser);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasBranch);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasTime);
    builder.append(","); //$NON-NLS-1$
    builder.append(lockAreasReadOnly);
    builder.append(" FROM "); //$NON-NLS-1$
    builder.append(lockAreas);
    sqlSelectAllLockAreas = builder.toString();

    builder.append(" WHERE "); //$NON-NLS-1$
    builder.append(lockAreasUser);
    builder.append(" LIKE ?"); //$NON-NLS-1$
    sqlSelectLockAreas = builder.toString();

    builder = new StringBuilder();
    builder.append("DELETE FROM "); //$NON-NLS-1$
    builder.append(lockAreas);
    builder.append(" WHERE "); //$NON-NLS-1$
    builder.append(lockAreasID);
    builder.append("=?"); //$NON-NLS-1$
    sqlDeleteLockArea = builder.toString();

    builder = new StringBuilder();
    builder.append("SELECT "); //$NON-NLS-1$
    builder.append(locksObject);
    builder.append(","); //$NON-NLS-1$
    builder.append(locksGrade);
    builder.append(" FROM "); //$NON-NLS-1$
    builder.append(locks);
    builder.append(" WHERE "); //$NON-NLS-1$
    builder.append(locksArea);
    builder.append("=?"); //$NON-NLS-1$
    sqlSelectLocks = builder.toString();

    builder = new StringBuilder();
    builder.append("SELECT "); //$NON-NLS-1$
    builder.append(locksGrade);
    builder.append(" FROM "); //$NON-NLS-1$
    builder.append(locks);
    builder.append(" WHERE "); //$NON-NLS-1$
    builder.append(locksArea);
    builder.append("=? AND "); //$NON-NLS-1$
    builder.append(locksObject);
    builder.append("=?"); //$NON-NLS-1$
    sqlSelectLock = builder.toString();

    builder = new StringBuilder();
    builder.append("INSERT INTO "); //$NON-NLS-1$
    builder.append(locks);
    builder.append("("); //$NON-NLS-1$
    builder.append(locksArea);
    builder.append(","); //$NON-NLS-1$
    builder.append(locksObject);
    builder.append(","); //$NON-NLS-1$
    builder.append(locksGrade);
    builder.append(") VALUES (?, ?, ?)"); //$NON-NLS-1$
    sqlInsertLock = builder.toString();

    builder = new StringBuilder();
    builder.append("UPDATE "); //$NON-NLS-1$
    builder.append(locks);
    builder.append(" SET "); //$NON-NLS-1$
    builder.append(locksGrade);
    builder.append("=? "); //$NON-NLS-1$
    builder.append(" WHERE "); //$NON-NLS-1$
    builder.append(locksArea);
    builder.append("=? AND "); //$NON-NLS-1$
    builder.append(locksObject);
    builder.append("=?"); //$NON-NLS-1$
    sqlUpdateLock = builder.toString();

    builder = new StringBuilder();
    builder.append("DELETE FROM "); //$NON-NLS-1$
    builder.append(locks);
    builder.append(" WHERE "); //$NON-NLS-1$
    builder.append(locksArea);
    builder.append("=? AND "); //$NON-NLS-1$
    builder.append(locksObject);
    builder.append("=?"); //$NON-NLS-1$
    sqlDeleteLock = builder.toString();

    builder = new StringBuilder();
    builder.append("DELETE FROM "); //$NON-NLS-1$
    builder.append(locks);
    builder.append(" WHERE "); //$NON-NLS-1$
    builder.append(locksArea);
    builder.append("=?"); //$NON-NLS-1$
    sqlDeleteLocks = builder.toString();
  }

  private String getNextDurableLockingID(DBStoreAccessor accessor)
  {
    for (;;)
    {
      String durableLockingID = CDOLockUtil.createDurableLockingID();

      try
      {
        getLockArea(accessor, durableLockingID); // Check uniqueness
        // Not unique; try once more...
      }
      catch (LockAreaNotFoundException ex)
      {
        return durableLockingID;
      }
    }
  }

  private LockArea makeLockArea(DBStoreAccessor accessor, String durableLockingID, String userID, int branchID,
      long timeStamp, boolean readOnly)
  {
    CDOBranchPoint branchPoint = branchManager.getBranch(branchID).getPoint(timeStamp);
    Map<CDOID, LockGrade> lockMap = getLockMap(accessor, durableLockingID);
    return CDOLockUtil.createLockArea(durableLockingID, userID, branchPoint, readOnly, lockMap);
  }

  private Map<CDOID, LockGrade> getLockMap(DBStoreAccessor accessor, String durableLockingID)
  {
    IPreparedStatementCache statementCache = accessor.getStatementCache();
    PreparedStatement stmt = null;
    ResultSet resultSet = null;

    try
    {
      stmt = statementCache.getPreparedStatement(sqlSelectLocks, ReuseProbability.MEDIUM);
      stmt.setString(1, durableLockingID);
      resultSet = stmt.executeQuery();

      Map<CDOID, LockGrade> lockMap = new HashMap<CDOID, LockGrade>();
      while (resultSet.next())
      {
        CDOID id = idHandler.getCDOID(resultSet, 1);
        int grade = resultSet.getInt(2);

        lockMap.put(id, LockGrade.get(grade));
      }

      return lockMap;
    }
    catch (SQLException e)
    {
      throw new DBException(e);
    }
    finally
    {
      DBUtil.close(resultSet);
      statementCache.releasePreparedStatement(stmt);
    }
  }

  private void changeLocks(DBStoreAccessor accessor, String durableLockingID, LockType type,
      Collection<? extends Object> keys, boolean on)
  {
    if (keys.isEmpty())
    {
      return;
    }

    IPreparedStatementCache statementCache = accessor.getStatementCache();
    PreparedStatement stmtSelect = null;
    PreparedStatement stmtInsertOrDelete = null;
    PreparedStatement stmtUpdate = null;
    ResultSet resultSet = null;

    try
    {
      stmtSelect = statementCache.getPreparedStatement(sqlSelectLock, ReuseProbability.MEDIUM);
      stmtSelect.setString(1, durableLockingID);

      String sql = on ? sqlInsertLock : sqlDeleteLock;
      stmtInsertOrDelete = statementCache.getPreparedStatement(sql, ReuseProbability.MEDIUM);
      stmtInsertOrDelete.setString(1, durableLockingID);

      stmtUpdate = statementCache.getPreparedStatement(sqlUpdateLock, ReuseProbability.MEDIUM);
      stmtUpdate.setString(2, durableLockingID);

      InternalLockManager lockManager = accessor.getStore().getRepository().getLockManager();
      for (Object key : keys)
      {
        CDOID id = lockManager.getLockKeyID(key);
        idHandler.setCDOID(stmtSelect, 2, id);
        resultSet = stmtSelect.executeQuery();

        LockGrade oldGrade = LockGrade.NONE;
        if (resultSet.next())
        {
          oldGrade = LockGrade.get(resultSet.getInt(1));
        }

        LockGrade newGrade = oldGrade.getUpdated(type, on);
        if (on && oldGrade == LockGrade.NONE)
        {
          idHandler.setCDOID(stmtInsertOrDelete, 2, id);
          stmtInsertOrDelete.setInt(3, newGrade.getValue());
          DBUtil.update(stmtInsertOrDelete, true);
        }
        else if (!on && newGrade == LockGrade.NONE)
        {
          idHandler.setCDOID(stmtInsertOrDelete, 2, id);
          DBUtil.update(stmtInsertOrDelete, true);
        }
        else
        {
          stmtUpdate.setInt(1, newGrade.getValue());
          idHandler.setCDOID(stmtUpdate, 3, id);
          DBUtil.update(stmtUpdate, true);
        }
      }

      accessor.getConnection().commit();
    }
    catch (SQLException e)
    {
      throw new DBException(e);
    }
    finally
    {
      DBUtil.close(resultSet);
      statementCache.releasePreparedStatement(stmtUpdate);
      statementCache.releasePreparedStatement(stmtInsertOrDelete);
      statementCache.releasePreparedStatement(stmtSelect);
    }
  }
}
