/*
   Derby - Class org.apache.derbyTesting.functionTests.tests.memorydb.MogTest

   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
 */

package org.apache.derbyTesting.functionTests.tests.memorydb;

import junit.framework.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.apache.derbyTesting.junit.BaseJDBCTestCase;
import org.apache.derbyTesting.junit.TestConfiguration;

/**
 * Test consistency among (GenMog), (SampMog), and (ClusMog).
 */
public class MogTest extends BaseJDBCTestCase {

  public MogTest(String name) { super(name); }
	
  public static Test suite() {
    return TestConfiguration.defaultSuite(MogTest.class);
  }

  /** Dispose of objects after testing. */
  protected void tearDown() throws Exception
  {
    super.tearDown();
  }

  /**
   * Calculates by using the default directory/disk storage back end.
   *
   * @throws SQLException if the test fails
   */
  public void testClusMogOnDisk()
          throws SQLException {
      long start = System.currentTimeMillis();
      doTestClusMog(getConnection());
      println("duration-on-disk: " + (System.currentTimeMillis() - start));
  }

  /**
   * Calculates by using the in-memory storage back end.
   *
   * @throws SQLException if the test fails
   */
  public void testClusMogInMemory()
          throws SQLException {
      long start = System.currentTimeMillis();
      // Close the connection explicitly here, since the test framework won't
      // do it for us when we create it manually.
      Connection conn = obtainConnection();
      try {
          doTestClusMog(conn);
      } finally {
          try {
              conn.rollback();
              conn.close();
          } catch (SQLException sqle) {
              // Ignore exceptions during close.
          }
          dropInMemoryDb();
      }
      println("duration-in-memory: " + (System.currentTimeMillis() - start));
  }

  /**
   * Test consistency between (ClusMog) and (ClusMogSQL).
   * @throws SQLException if something goes wrong
   */
  public void doTestClusMog(Connection conn)
          throws SQLException {

    // Initialize test objects.
    // NOTE: Due to instability in the test, the seed has been fixed.
    //       See DERBY-4209 (and DERBY-4085).
    //final long _seed = System.currentTimeMillis();
    final long _seed = 1241411544935L;
    java.util.Random rng = new java.util.Random(_seed);
    /** MOG generator being tested */
    GenMog genMog = new GenMog(rng);
    /** MOG sampler being tested */
    SampMog sampMog = new SampMog(rng);
    /** clustering object being tested */
    ClusMog clusMog = new ClusMog();
    /** clustering object being tested */
    ClusMogSQL clusMogSql = new ClusMogSQL(conn);
    clusMogSql.setUnique(rng.nextInt());

    println(getName() + " using random seed: " + _seed);
    final int max_ns = 10 * ClusMog.min_sample_size_per_cluster * GenMog.max_n;
    final double sample[] = new double[max_ns];
    final double center[] = new double[GenMog.max_n];
    final int niter = 1;
    for (int i=niter; i>0; --i) {
      // Generate a MOG configuration.
      genMog.generate();
      // Compute a sample size.
      final int min_ns = ClusMog.min_sample_size_per_cluster * genMog.n;
      final int ns = min_ns + rng.nextInt(max_ns - min_ns);
      println("ns = " + ns);
      // Generate samples from the MOG distribution.
      sampMog.set(genMog.n, genMog.weight, genMog.mean, genMog.var);
      sampMog.generate(ns, sample);

      // Produce an initial cluster center configuration.
      ClusMog.uniform(genMog.n, center, ns, sample);
      // Cluster the samples to recover the MOG configuration.
      clusMog.cluster(genMog.n, center, ns, sample);
      // Cluster the samples again, using SQL.
      clusMogSql.clusterSQL(genMog.n, center, ns, sample);
      // Compare the computed MOG configurations.
      assertEquals("MOG configurations differ, seed=" + _seed,
              clusMog.n, clusMogSql.n);
      compare(clusMog.n, clusMog.weight, clusMogSql.weight, _seed);
      compare(clusMog.n, clusMog.mean, clusMogSql.mean, _seed);
      compare(clusMog.n, clusMog.var, clusMogSql.var, _seed);

      // Produce another initial cluster center configuration.
      ClusMog.random(genMog.n, center, ns, sample, rng);
      // Cluster the samples to recover the MOG configuration.
      clusMog.cluster(genMog.n, center, ns, sample);
      // Cluster the samples again, using SQL.
      clusMogSql.clusterSQL(genMog.n, center, ns, sample);
      // Compare the computed MOG configurations.
      assertEquals("MOG configurations differ, seed=" + _seed,
              clusMog.n, clusMogSql.n);
      compare(clusMog.n, clusMog.weight, clusMogSql.weight, _seed);
      compare(clusMog.n, clusMog.mean, clusMogSql.mean, _seed);
      compare(clusMog.n, clusMog.var, clusMogSql.var, _seed);
    }
  }

  /** Compare two floating-point arrays, with tolerance. */
  private void compare(int n, double ones[], double oths[], final long seed)
  {
    final double thresh = 1.0e-6;
    for (int i=0; i<n; ++i) {
      final double one = ones[i];
      final double oth = oths[i];
      final double dif = Math.abs(one - oth);
      final double err = dif / (1.0 + Math.abs(one));
      // Use if to avoid unnecessary string concatenation.
      if (err >= thresh) {
        fail("Error too big;" + err + " >= " + thresh + ", seed=" + seed);
      }
    }
  }

  /**
   * Obtains a connection to an in-memory database.
   *
   * @return A connection to an in-memory database.
   * @throws SQLException if obtaining the connection fails
   */
  private Connection obtainConnection()
        throws SQLException {
    try {
        if (usingDerbyNetClient()) {
            Class.forName("org.apache.derby.jdbc.ClientDriver");
        } else {
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        }
    } catch (Exception e) {
        SQLException sqle =  new SQLException(e.getMessage());
        sqle.initCause(e);
        throw sqle;
    }
    StringBuffer sb = constructUrl().append(";create=true");
    return DriverManager.getConnection(sb.toString());
  }

  /**
   * Drops the database used by the test.
   *
   * @throws SQLException if dropping the database fails
   */
    private void dropInMemoryDb()
            throws SQLException {
        StringBuffer sb = constructUrl().append(";drop=true");
        try {
            DriverManager.getConnection(sb.toString());
            fail("Dropping database should have raised exception.");
        } catch (SQLException sqle) {
            assertSQLState("08006", sqle);
        }
    }

    /**
     * Constructs the default URL for the in-memory test database.
     *
     * @return A database URL (without any connection attributes).
     */
    private StringBuffer constructUrl() {
        StringBuffer sb = new StringBuffer("jdbc:derby:");
        if (usingEmbedded()) {
            sb.append("memory:");
        } else {
            // This is a hack. Change this when proper support for the in-memory
            // back end has been implemented.
            sb.append("//");
            sb.append(TestConfiguration.getCurrent().getHostName());
            sb.append(':');
            sb.append(TestConfiguration.getCurrent().getPort());
            sb.append('/');
            sb.append("memory:");
        }
        sb.append("MogTestDb");
        return sb;
    }
}
