/******************************************************************************
 *
 * A component of the Greenstone digital library software from the New Zealand
 * Digital Library Project at the # University of Waikato, New Zealand.
 * Copyright (C) 2006 New Zealand Digital Library Project
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 *****************************************************************************/
/** @author jmt12, GSDL **/
package org.nzdl.gsdl;

import java.io.*;
import java.lang.*;
import java.nio.file.*;
import java.util.*;

/** @class GSInfoDB
 */
public class GSInfoDB
{
  private boolean debug = false;

  private PrintWriter dbwriter;
  private Process dbprocess;

  private Path file_path;
  private Path tmp_file_path;

  private String infodb_type;

  // Seventy hyphens - GDBM's default record separator
  private static String separator = "----------------------------------------------------------------------";

  /** @function GSInfoDB(String)
   */
  public GSInfoDB(String gsdl_home, String infodb_type, String file)
  {
    if (debug)
    {
      System.err.println("[DEBUG] GSInfoDB(" + gsdl_home + ", " + infodb_type + ", " + file + ")");
    }
    this.infodb_type = infodb_type;
    // most of the following code throws IOExceptions...
    try
    {
      this.file_path = FileSystems.getDefault().getPath(file);
      Path tmp_dir = FileSystems.getDefault().getPath("/tmp");
      this.tmp_file_path = Files.createTempFile(tmp_dir, null, "." + infodb_type);
      if (debug)
      {
        System.err.println("[DEBUG] Temporary file path: " + tmp_file_path);
      }
      ProcessBuilder pb = new ProcessBuilder(gsdl_home + "/ext/tdb-edit/linux/bin/txt2tdb", "-append", tmp_file_path.toString());
      if (debug)
      {
        System.err.println("[DEBUG] Command: " + pb.command());
      }
      // - alter environment
      Map<String, String> pb_env = pb.environment();
      pb_env.put("PATH", gsdl_home + "/ext/tdb-edit/linux/bin:" + gsdl_home + "/ext/tdb-edit/bin/script:" + pb_env.get("PATH"));
      pb_env.put("LD_LIBRARY_PATH", gsdl_home + "/ext/tdb-edit/linux/lib:" + pb_env.get("LD_LIBRARY_PATH"));
      // Start the writer listening
      dbprocess = pb.start();
      OutputStream os = dbprocess.getOutputStream();
      dbwriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os)));
    }
    catch (Exception ex)
    {
      System.err.println("Error! Failed to open GSInfoBD: " + ex.toString());
      ex.printStackTrace();
    }
  }
  /** GSInfoDB(String) **/


  /** @function close()
   */
  public void close()
  {
    if (debug)
    {
      System.err.println("[DEBUG] GSInfoBD::close()");
    }
    try
    {
      dbwriter.close();
      dbprocess.waitFor();
      if (debug)
      {
        System.err.println("[DEBUG] temporary database size: " + this.tmp_file_path.toFile().length() + " bytes");
      }
      // Move the database into its final location
      Files.move(this.tmp_file_path, this.file_path, StandardCopyOption.REPLACE_EXISTING);


      Runtime rut = Runtime.getRuntime();
      Process process = rut.exec(new String[] {"mv", this.tmp_file_path.toString(), this.file_path.toString()});
      // The below always says the file doesn't exist over NFS?
      if (!this.file_path.toFile().exists())
      {
        System.err.println("Error! Failed to move database file: " + this.tmp_file_path.toString() + " => " + this.file_path.toString());
      }
      if (debug)
      {
        System.err.println("[DEBUG] final database size: " + this.file_path.toFile().length() + " bytes");
      }
    }
    catch (Exception ex)
    {
      System.err.println("Error! Failed to close GSInfoBD: " + ex.toString());
      ex.printStackTrace();
    }
  }
  /** close() **/


  /** @function write(String payload)
   */
  public void writeEntry(String payload)
  {
    if (debug)
    {
      System.err.println("[DEBUG] GSInfoDB::writeEntry(" + payload + ")");
    }
    try
    {
      dbwriter.println(payload);
      dbwriter.println(separator);
    }
    catch (Exception ex)
    {
      System.err.println("Error! Failed to write to GSInfoDB: " + ex.toString());
      ex.printStackTrace();
    }
  }
  /** write(String payload) **/

}
/** class GSInfoDB **/

