/**
 * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 * 
 * Please see distribution for license.
 */
package com.opengamma.maven.db;

import java.io.File;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.hsqldb.jdbcDriver;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;

import com.jolbox.bonecp.BoneCPDataSource;
import com.opengamma.maven.MojoUtils;
import com.opengamma.util.db.DbConnector;
import com.opengamma.util.db.HSQLDbDialect;
import com.opengamma.util.db.management.DbManagement;
import com.opengamma.util.db.management.HSQLDbManagement;
import com.opengamma.util.db.script.DbScriptDirectory;
import com.opengamma.util.db.script.DbScriptReader;
import com.opengamma.util.db.script.FileDbScriptDirectory;
import com.opengamma.util.db.script.ZipFileDbScriptDirectory;
import com.opengamma.util.db.tool.DbCreateOperation;
import com.opengamma.util.db.tool.DbToolContext;

/**
 * Maven plugin wrapping a {@link DbCreateOperation} to create a local HSQL database.
 * <p>
 * For more advanced or custom database operations, use the associated tools from the command line.
 * 
 * @goal hsqldb-create
 * @requiresDependencyResolution compile
 */
public class HSQLDbCreateMojo extends AbstractMojo {

  /**
   * @parameter alias="dbPath"
   * @required
   */
  private String _dbPath;
  /**
   * @parameter alias="username"
   * @required
   */
  private String _username;
  /**
   * @parameter alias="password"
   * @required
   */
  private String _password;
  /**
   * @parameter alias="scriptsArtifact"
   */
  private String _scriptsArtifact;
  /**
   * @parameter alias="scriptsPath"
   * @required
   */
  private String _scriptsPath;
  
  /**
   * @component
   */
  private MavenProject _project;
  
  @Override
  public void execute() throws MojoExecutionException, MojoFailureException {
    String dbPath = _dbPath;
    int lastSlashIdx = dbPath.lastIndexOf("/");
    if (lastSlashIdx == -1) {
      throw new MojoExecutionException("dbPath must contain '/' before the database name");
    }
    String dbHost = dbPath.substring(0, lastSlashIdx);
    String catalog = dbPath.substring(lastSlashIdx + 1);
    
    BoneCPDataSource dataSource = new BoneCPDataSource();
    dataSource.setDriverClass(jdbcDriver.class.getName());
    dataSource.setJdbcUrl("jdbc:hsqldb:file:" + dbPath);
    dataSource.setUsername(_username);
    dataSource.setPassword(_password);
    dataSource.setPoolName("hsqldb");
    dataSource.setPartitionCount(1);
    dataSource.setAcquireIncrement(1);
    dataSource.setMinConnectionsPerPartition(1);
    dataSource.setMaxConnectionsPerPartition(1);
    
    SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
    TransactionTemplate transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource), new DefaultTransactionDefinition());
    
    DbToolContext dbToolContext = new DbToolContext();
    try {
      DbManagement dbManagement = HSQLDbManagement.getInstance();
      dbManagement.initialise(dbHost, _username, _password);
      dbToolContext.setDbManagement(dbManagement);
      dbToolContext.setDbConnector(new DbConnector("hsqldb", new HSQLDbDialect(), dataSource, jdbcTemplate, null, transactionTemplate));
      dbToolContext.setCatalog(catalog);
      
      DbScriptDirectory scriptsBaseDir;
      if (_scriptsArtifact != null) {
        File scriptsResource = MojoUtils.getArtifactFile(_scriptsArtifact, _project);
        scriptsBaseDir = new ZipFileDbScriptDirectory(scriptsResource, _scriptsPath);
      } else {
        scriptsBaseDir = new FileDbScriptDirectory(new File(_scriptsPath));
      }
      dbToolContext.setScriptReader(new DbScriptReader(scriptsBaseDir));
      new DbCreateOperation(dbToolContext, true, null, true).execute();
      dbToolContext.close();
    } catch (Exception e) {
      throw new MojoExecutionException("Error creating database schemas", e);
    } finally {
      dbToolContext.close();
    }
  }

}

@@ -2234,330 +2234,8 @@
 n %7B%0A
-    String dbPath = _dbPath;%0A    int lastSlashIdx = dbPath.lastIndexOf(%22/%22);%0A    if (lastSlashIdx == -1) %7B%0A      throw new MojoExecutionException(%22dbPath must contain '/' before the database name%22);%0A    %7D%0A    String dbHost = dbPath.substring(0, lastSlashIdx);%0A    String catalog = dbPath.substring(lastSlashIdx + 1);%0A    %0A
     
@@ -2284,24 +2284,24 @@
 taSource();%0A
+
     dataSour
@@ -2395,16 +2395,17 @@
 ile:%22 + 
+_
 dbPath);
@@ -2642,24 +2642,24 @@
 rtition(1);%0A
-
     dataSour
@@ -2696,24 +2696,362 @@
 on(1);%0A    %0A
+    String dbPath = dataSource.getJdbcUrl();%0A    int lastSlashIdx = dbPath.lastIndexOf(%22/%22);%0A    if (lastSlashIdx == -1) %7B%0A      throw new MojoExecutionException(%22dbPath must contain '/' before the database name%22);%0A    %7D%0A    String dbHost = dbPath.substring(0, lastSlashIdx);%0A    String catalog = dbPath.substring(lastSlashIdx + 1);%0A    %0A
     SimpleJd

Use JDBC URL from data source to ensure correctly formatted