/* Copyright (C) 2020 Patrick G. Durand
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  You may obtain a copy of the License at
 *
 *     https://www.gnu.org/licenses/agpl-3.0.txt
 *
 *  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 Affero General Public License for more details.
 */
package bzh.plealog.dbmirror.task;

import java.io.File;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import bzh.plealog.dbmirror.util.Utils;
import bzh.plealog.dbmirror.util.conf.Configuration;
import bzh.plealog.dbmirror.util.conf.DBMSAbstractConfig;
import bzh.plealog.dbmirror.util.log.LoggerCentral;
import bzh.plealog.dbmirror.util.runner.CommandArgument;
import bzh.plealog.dbmirror.util.runner.DBMSExecNativeCommand;
import bzh.plealog.dbmirror.util.runner.ExecMonitor;

/**
 * A task capable of executing an external script.
 * 
 * @author Patrick G. Durand
 */
public class PTaskExecScript extends PAbstractTask {

  private String                _scriptName;
  private String                _scriptCmd;
  private String                _dbInstallationPath;
  private String                _curFile;
  private String                _errMsg;
  protected Map<String, String> _args;
  
  //mandatory arguments user has to provide in 'script()' task
  private static final String SCRIPT_NAME = "name";
  private static final String SCRIPT_CMD_PATH = "path";
  //arguments passed in to the calling script
  private static final String INST_DIR_ARG = "-d"; //path to bank installation (unit and global tasks)
  private static final String INST_FILE_ARG = "-f"; // path to file (unit task only)
  
  private static final Log LOGGER     = LogFactory
                                          .getLog(DBMSAbstractConfig.KDMS_ROOTLOG_CATEGORY
                                              + ".PTaskEngine");

  /**
   * Constructor.
   * 
   * @param dbPath path to bank installation (unit and global tasks)
   * @param currentFile path to file (unit task only)
   */
  public PTaskExecScript(String dbPath, String currentFile) {
    _dbInstallationPath = dbPath;
    _curFile = currentFile;
  }

  /**
   * Implementation of KLTask interface.
   */
  public void setParameters(String params) {
    if (params == null) {
      _args = new Hashtable<String, String>();
    }
    else {
      _args = Utils.getTaskArguments(params);
      _scriptName = _args.get(SCRIPT_NAME);
      _scriptCmd = _args.get(SCRIPT_CMD_PATH);
    }
    if (_dbInstallationPath!=null) {
      _args.put(INST_DIR_ARG, _dbInstallationPath);
      
    }
    if (_curFile!=null) {
      _args.put(INST_FILE_ARG, _curFile);
      
    }
  }

  /**
   * Implementation of KLTask interface.
   */
  public String getName() {
    return "script";
  }

  /**
   * Implementation of KLTask interface.
   */
  public String getUserFriendlyName() {
    return "executing external script";
  }

  /**
   * Implementation of KLTask interface.
   */
  public String getErrorMsg() {
    return _errMsg;
  }

  /**
   * Implementation of KLTask interface.
   */
  public boolean execute() {
    LoggerCentral.info(LOGGER, getUserFriendlyName());
    
    //mandatory arguments user must provide when using 'script()' task
    if (_scriptName == null) {
      _errMsg = "command name is unknown";
      return false;
    }
    
    LoggerCentral.info(LOGGER, SCRIPT_NAME+": "+_scriptName);
    
    if (_scriptCmd == null) {
      _errMsg = "command to execute is unknown";
      return false;
    }
    
    //figures out whether or not _scriptCmd is accessible
    File f = new File(_scriptCmd);
    //if user only provides script name, we suppose it is located in standard conf/scripts dir
    if (f.getParent()==null) {
      _scriptCmd = DBMSAbstractConfig.getConfPath(Configuration.SCRIPTS)+_scriptCmd;
    }

    LoggerCentral.info(LOGGER, SCRIPT_CMD_PATH+": "+_scriptCmd);

    //internal problem: not path to bank installation
    if (_dbInstallationPath == null) {
      _errMsg = "installation path is unknown";
      return false;
    }
    
    //start command
    DBMSExecNativeCommand executor = new DBMSExecNativeCommand(new MyMonitor());
    LinkedHashMap<String, CommandArgument> params;
    params = new LinkedHashMap<String, CommandArgument>();
    params.put(INST_DIR_ARG, new CommandArgument(_dbInstallationPath, true));
    if (_curFile!=null) {
      params.put(INST_FILE_ARG, new CommandArgument(_curFile, true));
    }
    executor.executeAndWait(_scriptCmd, params);
    
    return executor.getExitCode()==0;
  }

  

  private class MyMonitor implements ExecMonitor{
    public void warn(String msg) {
      if (_errMsg==null) {
        _errMsg = msg;
      }
      else {
        _errMsg += "\n";
        _errMsg += msg;
      }
    }

    public void info(String msg) {
      LoggerCentral.info(LOGGER, msg);
    }
  }
}

enable the use of external tasks... forgot commit new class