/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

package pt.webdetails.cpf;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.pentaho.platform.api.engine.IPluginManager;
import org.pentaho.platform.api.engine.ISystemSettings;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.util.xml.dom4j.XmlDom4JHelper;


public abstract class PluginSettings {
  
  public static final String ENCODING = "utf-8";

  protected static Log logger = LogFactory.getLog(PluginSettings.class);
  private static IPluginManager pluginManager;
  
  public abstract String getPluginName();
  
  public String getPluginSystemDir(){
    return getPluginName() + "/";
  }
  
  protected static final String SETTINGS_FILE = "settings.xml"; 
  
  private static IPluginManager getPluginManager(){
    if(pluginManager == null){
      pluginManager = PentahoSystem.get(IPluginManager.class);
    }
    return pluginManager;
  }
  
  protected boolean getBooleanSetting(String section, boolean nullValue){
    String setting = getStringSetting(section, null);
    if(setting != null){
      return Boolean.parseBoolean(setting);
    }
    return nullValue;
  }
  
  protected String getStringSetting(String section, String defaultValue){
    return (String) getPluginManager().getPluginSetting(getPluginName(), section, defaultValue);
  }

  protected static String getSolutionPath(String path){
    return PentahoSystem.getApplicationContext().getSolutionPath(path);
  }
  
  /**
   * Writes a setting directly to .xml. Does not refresh global config.
   * @param section
   * @param value
   * @return
   */
  protected boolean writeSetting(String section, String value){
    Document settings = null;
    String settingsFilePath = PentahoSystem.getApplicationContext().getSolutionPath("system/" + getPluginSystemDir() + SETTINGS_FILE);
    File settingsFile = new File(settingsFilePath); 
    String nodePath = "settings/" + section;
    
    try {
      settings = XmlDom4JHelper.getDocFromFile(settingsFile, null);// getDocFromFile(settingsFilePath, null);
    } catch (DocumentException e) {
      logger.error(e);
    } catch (IOException e) {
      logger.error(e);
    }
    if(settings != null){
      Node node = settings.selectSingleNode(nodePath);
      if(node != null){
        node.setText(value);
        FileWriter writer = null;
        try {
          writer = new FileWriter(settingsFile);
          settings.write(writer);
          writer.flush();
          return true;
        } catch (IOException e) {
          logger.error(e);
        }
        finally {
          IOUtils.closeQuietly(writer);
        }
      }
      else {
        logger.error("Couldn't find node");
      }
    }
    else {
      logger.error("Unable to open " + settingsFilePath);
    }
    return false;    
  }

  @SuppressWarnings("unchecked")
  protected List<Element> getSettingsXmlSection(String section) {
    ISystemSettings settings = PentahoSystem.getSystemSettings();
    List<Element> elements = settings.getSystemSettings(getPluginSystemDir() + SETTINGS_FILE, section);
    return elements;
  }
  
}

@@ -365,16 +365,60 @@
 OUtils;%0A
+import org.apache.commons.lang.StringUtils;%0A
 import o
@@ -1975,16 +1975,22 @@
 %0A  %7D%0A  %0A
+  %0A  %0A
   /**%0A  
@@ -2029,18 +2029,12 @@
 .xml
-. Does not
+ and
  ref
@@ -2103,16 +2103,42 @@
  @return
+ whether value was written
 %0A   */%0A 
@@ -2807,24 +2807,120 @@
 e != null)%7B%0A
+        String oldValue = node.getText();%0A//        if(!StringUtils.equals(oldValue, value))%7B%0A  
         node
@@ -2932,24 +2932,26 @@
 ext(value);%0A
+  
         File
@@ -2976,30 +2976,34 @@
 ll;%0A        
+ 
+ 
 try %7B%0A
+  
           wr
@@ -3045,24 +3045,26 @@
 ;%0A          
+  
 settings.wri
@@ -3067,32 +3067,34 @@
 .write(writer);%0A
+  
           writer
@@ -3099,24 +3099,254 @@
 er.flush();%0A
+            //TODO: in future should only refresh relevant cache, not the whole thing%0A            logger.debug(%22changed '%22 + section + %22' from '%22 + oldValue + %22' to '%22 + value +%22'%22);%0A            PentahoSystem.refreshSettings();%0A  
           re
@@ -3356,16 +3356,18 @@
 n true;%0A
+  
         
@@ -3394,32 +3394,34 @@
  e) %7B%0A          
+ 
+ 
 logger.error(e);
@@ -3421,32 +3421,34 @@
 ror(e);%0A        
+  
 %7D%0A        finall
@@ -3441,16 +3441,18 @@
         
+ 
+ 
 finally 
@@ -3449,24 +3449,26 @@
   finally %7B%0A
+  
           IO
@@ -3487,32 +3487,138 @@
 uietly(writer);%0A
+          %7D%0A//        %7D%0A//        else %7B%0A//          logger.debug(%22matches old value, left unchanged%22);%0A//
         %7D%0A      

refresh settings cache after write