package com.capgemini.reports.database.manager;

import com.capgemini.reports.ReportEnum;
import com.capgemini.reports.database.HibernateUtil;
import com.capgemini.reports.database.javabean.DbReportType;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import java.util.List;

/**
 * Hibernate manager for DBReportType JAVA bean.
 **/
public class MngReportType extends AbstractHibernateManager<DbReportType> {

  private static final String QUERY_ALL_SCHEDULABLE_REPORT_TYPES;

  static {
    String select = "select T0.code ";
    String from = "from " + DbReportType.class.getName() + " T0 ";
    String whereSchedulable = "where T0.isCandidateForScheduling = 'TRUE' ";
    String orderBy = "order by T0.code asc ";
    QUERY_ALL_SCHEDULABLE_REPORT_TYPES = select + from + whereSchedulable + orderBy;
  }

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

  /**
   * Create a new report type in database setting its mandatory attributes.
   */
  public DbReportType insert(Session session, final String aReportCode, final String aTitle, final Long aPriority, final String aRevisionRule) {
    DbReportType theReport = new DbReportType();

    // Assign default attribute values
    theReport.setCode(aReportCode);
    theReport.setTitle(aTitle);
    theReport.setPriority(aPriority);
    theReport.setRevisionRule(aRevisionRule);

    // Persist object
    session.save(theReport);
    return theReport;
  }

  /**
   * Search query for retrieving Report type using {@link ReportEnum}.
   */
  public DbReportType search(Session session, final ReportEnum report) {
    return searchBy(session, "code", report.getReportCode());
  }

  /**
   * Search query for retrieving Report type using its code.
   */
  private DbReportType searchByUid(Session session, final String aCode) {
    return searchBy(session, "code", aCode);
  }

  /**
   * Return true or false if current report is authorized.
   */
  public boolean isAuthorized(Session session, final String aCode) {
    return Boolean.valueOf(searchByUid(session, aCode).getReportAuthorized().toLowerCase());
  }

  /**
   * Return true or false if current report is authorized.
   */
  public boolean isAuthorized(final ReportEnum aReport) {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    try {
      return Boolean.valueOf(searchByUid(session, aReport.getReportCode()).getReportAuthorized().toLowerCase());
    }
    finally {
      session.close();
    }
  }

  /**
   * Obtain all the report types which are marked as Schedulable in the DB.
   */
  public List<String> getAllSchedulableReportTypes(Session session) {
    return session.createQuery(QUERY_ALL_SCHEDULABLE_REPORT_TYPES).list();
  }


  /**
   * Changes the 'authorization' status of a Report Type.
   */
  public DbReportType setReportActivation(final String reportCode, final String reportAuthorized) {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    try {
      Transaction transaction = session.beginTransaction();
      DbReportType dbReportType = searchBy(session, "code", reportCode);
      dbReportType.setReportAuthorized(reportAuthorized);
      update(session, dbReportType);
      transaction.commit();
      return dbReportType;
    }
    finally {
      session.close();
    }
  }
}
