/*
 * JBoss, the OpenSource EJB server
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package org.jboss.jdbc;

import java.io.File;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.File;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

import org.hsqldb.Embedded_Server;

import org.jboss.util.ServiceMBeanSupport;

/**
 *   Integration with Hypersonic SQL (http://hsqldb.oron.ch/). Starts a Hypersonic database in-VM.
 *
 *   @see HypersonicDatabaseMBean
 *   @author <a href="mailto:rickard.oberg@telkel.com">Rickard Öberg</a>
 *   @author <a href="mailto:Scott.Stark@jboss.org">Scott Stark</a>.
 *   @author Peter Fagerlund pf@iprobot.se @see stopService()
 *   @version $Revision: 1.8.4.2 $
 */
public class HypersonicDatabase
   extends ServiceMBeanSupport
   implements HypersonicDatabaseMBean
{
   // Constants -----------------------------------------------------
   
   // Attributes ----------------------------------------------------   
   // does not call System.exit() at shutdown
   Embedded_Server embeddedDBServer;
   
   String name = "jboss"; // Database name will be appended to "db/hypersonic/"
   int port = 1476; // Default port
   boolean silent = true;
   boolean trace = false;
   
   // Static --------------------------------------------------------
   
   // Constructors --------------------------------------------------
   public HypersonicDatabase()
   {
   }
   
   // Public --------------------------------------------------------
   // Settings
   public void setDatabase(String name)
   {
      this.name = name;
   }
   
   public String getDatabase()
   {
      return name;
   }
   
   public void setPort(int port)
   {
      this.port = port;
   }
   
   public int getPort()
   {
      return port;
   }
   
   public void setSilent(boolean silent)
   {
      this.silent = silent;
   }
   
   public boolean getSilent()
   {
      return silent;
   }
   
   public void setTrace(boolean trace)
   {
      this.trace = trace;
   }
   
   public boolean getTrace()
   {
      return trace;
   }
   
   public String getName()
   {
      return "Hypersonic";
   }

   public void startService()
      throws Exception
   {
      // Get DB directory
      File jbossHomeDir = new File(System.getProperty("jboss.home"));
      String dbPath = "db"+File.separator+"hypersonic"+File.separator+name;
      File dbName = new File(jbossHomeDir, dbPath);
      // Create startup arguments
      String[] args = new String[]
      {
         "-database", dbName.toString(),
         "-port", port+"",
         "-silent", silent+"",
         "-trace", trace+""
      };
      Throwable[] error = {null};
      embeddedDBServer = new Embedded_Server();
      synchronized( error )
      {
         embeddedDBServer.runEmbedded(args, error);
         error.wait();
      }      
      log.info("Database started");
   }

   /**
    *    @author Peter Fagerlund pf@iprobot.com
    *
    *    marcf FIXME: it doesn't seem to work very well on Linux...
    *    is there a way to hack the hsqldb to get a more tight control over the shutdown
    *
    *    We now close the connection clean by calling the
    *    serverSocket throught jdbc. The MBeanServer calls
    *    this method at closing time
    */
   public void stopService()
   {
      Connection connection;
      Statement statement;
      
      String cmd              = "SHUTDOWN";
      String jdbcDriver       = "org.hsqldb.jdbcDriver";
      String dbStrVersion_1_4 = "jdbc:HypersonicSQL:hsql://localhost:"+port;
      String dbStrVersion_1_6 = "jdbc:hsqldb:hsql://localhost:"+port;
      String user             = "sa";
      String password         = "";
      
      try
      {         
         connection=DriverManager.getConnection(dbStrVersion_1_6, user, password);
         statement=connection.createStatement();
         statement.executeQuery(cmd);
         
         log.info("Database closed clean");         
      }
      catch(Throwable e)
      {
         log.error("Database closed failed", e);
      }      
      embeddedDBServer = null;
   }
   // Protected -----------------------------------------------------
}
