package com.capgemini.reports.database.manager;

import com.capgemini.framework.common.DateHelper;
import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.reports.database.HibernateUtil;
import com.capgemini.reports.database.javabean.DbMemMonitor;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

/**
 * Hibernate manager for DBReport JAVA bean.
 **/
public class MngMemMonitor extends AbstractHibernateManager<DbMemMonitor> {

  private static final int THOUSAND = 1000;
  private static final int FIVE = 5;
  /**
   * Quantity of trace displayed.
   **/
  private static final int MAX_MONITOR_TRACE_COUNT = SettingsHelper.getMemoryMaxCount();
  /**
   * Elapsed seconds between each trace.
   **/
  private static final int MONITOR_FREQUENCY = SettingsHelper.getMemoryFrequency();

  @Override
  public Class<DbMemMonitor> getManagedClass() {
    return DbMemMonitor.class;
  }

  /**
   * Create a memory monitoring trace.
   *
   * @param aFreeMemory  free memory
   * @param anUsedMemory used memory
   * @param aMaxMemory   max memory in session
   * @param aMaxPercent  max memory percent
   * @param aTotalMemory total memory
   * @return Monitoring trace object
   */
  public DbMemMonitor insert(final Double aFreeMemory, final Double anUsedMemory, final Double aMaxMemory, final Double aMaxPercent,
                             final Double aTotalMemory) {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    try {
      Transaction transaction = session.beginTransaction();
      DbMemMonitor theMemMonitor = new DbMemMonitor();

      // Assign default attribute values
      theMemMonitor.setMonitorDate(DateHelper.getCurrentSqlTimestamp());

      // Assign specific attribute values
      theMemMonitor.setFreeMemory(aFreeMemory);
      theMemMonitor.setMaxMemory(aMaxMemory);
      theMemMonitor.setMaxPercent(aMaxPercent);
      theMemMonitor.setTotalMemory(aTotalMemory);
      theMemMonitor.setUsedMemory(anUsedMemory);

      // Persist object
      session.save(theMemMonitor);
      transaction.commit();

      return theMemMonitor;
    }
    finally {
      session.close();
    }
  }

  /**
   * Search last memory monitor traces.
   */
  public List<DbMemMonitor> searchMemMonitor() {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    try {
      String theHqlQuery = "select T0 from DbMemMonitor T0 where monitorDate > :paramMonitorDate order by T0.id desc";
      Query theQuery = session.createQuery(theHqlQuery);

      long theSecDelta = MAX_MONITOR_TRACE_COUNT * MONITOR_FREQUENCY + FIVE;
      long theMsDelta = theSecDelta * THOUSAND;
      theQuery.setTimestamp("paramMonitorDate", new Timestamp(new Date().getTime() - theMsDelta));
      theQuery.setMaxResults(MAX_MONITOR_TRACE_COUNT);

      return castAll(theQuery.list());
    }
    finally {
      session.close();
    }
  }
}
