package nxm.sys.net;

import nxm.sys.inc.ProvisionalUseOnly;
import nxm.sys.lib.Midas;
import nxm.sys.lib.OS;
import nxm.sys.lib.Parser;
import nxm.sys.lib.StringUtil;
import nxm.sys.lib.Table;

/**
  A class to display system information in an Browser.

  Supported requests are:
   Get?resultName
   Set?resultName=value
   Top
   Log
   DiskStats/auxName
   File/path

  @author Jeff Schoen

*/
public class HSystem extends HSource {

  private Midas M;

  /** HSystem Constructor
   *  @param name The name of the system resource
   *  @param M    The Midas context
   */
  public HSystem (String name, Midas M) {
    this.M = M;
    this.name = name+"/";
  }

  @Override
  public void handleRequest (String uri, HPage hp) {

    String option = uri.substring(name.length()+1);

    if (option.startsWith("Get?")) {
      getPage(option.substring(4),hp);
    }
    else if (option.startsWith("Set?")) {
      setPage(option.substring(4),hp);
    }
    else if (option.startsWith("Cmd?")) { // since 3.7.0 for BUG 2847
      cmdPage(option.substring(4),hp);
    }
    else if (option.startsWith("Top")) {
      topPage(hp);
    }
    else if (option.startsWith("Log")) {
      logPage(hp);
    }
    else if (option.startsWith("DiskStats/")) {
      String aux = option.substring(10);
      diskPage(aux,hp);
    }
    else {
      optPage(hp);
    }
  }

  /** Display system log information if available
   *  @param key key for system log information
   *  @param hp  HPage used to display system log information
   */
  public void getPage (String key, HPage hp) {
    Object value = M.results.get(key);
    hp.open();
    hp.writeln (key+"="+value);
    hp.close();
  }

  /** Set system log information of possible
   *  @param key key for system log information
   *  @param hp  HPage used to display system log information
   */
  public void setPage (String key, HPage hp) {
    int ie = key.indexOf("=");
    if (ie>0) {
      String value = key.substring(ie+1);
      key = key.substring(0,ie);
      M.results.setKey(key,value);
    }
    getPage(key,hp);
  }

  /** Display output of command
   *  @param cmd the command
   *  @param hp HPage used to display the output of the command
   */
  @ProvisionalUseOnly("Added in NeXtMidas 3.7.0")
  public void cmdPage (String cmd, HPage hp) {
    byte[] buf = new byte[8192];
    cmd = StringUtil.replaceAll(cmd,"%20"," ");   // spaces
    cmd = StringUtil.replaceAll(cmd,"%22","\"");  // quotes
    cmd = StringUtil.replaceAll(cmd,"%27","'");   // tic
    int bytes = OS.runCommand(cmd,0,buf);
    hp.openToBody("HSystem Cmd Page");
    hp.writeln ("<h3><a href='' onClick=\"location.reload(); return false;\">System Cmd="+cmd+"</a></h3>");
    hp.writeln ("<br><pre>");
    hp.write(buf,0,bytes);
    hp.writeln ("</pre>");
    hp.closeFromBody();
  }

  /** Display system log information if available
   *  @param hp HPage used to display system log information */
  public void logPage (HPage hp) {
    hp.openToBody("HSystem Log Page");
    hp.writeln ("<h3><a href='' onClick=\"location.reload(); return false;\">System Log</a></h3>");
    hp.writeln ("<br><pre>");
    hp.writeln ("Log File not opened");
    hp.writeln ("</pre>");
    hp.closeFromBody();
  }

  /** Display Top CPU/Memory Usage by process
   *  @param hp HPage used to display Top CPU/Memory Usage by process */
  public void topPage (HPage hp) {
    byte[] buf = new byte[8192];
    int bytes = OS.getStats(0,buf);
    hp.openToBody("HSystem Top Page");
    hp.writeln ("<h3><a href='' onClick=\"location.reload(); return false;\">System Top</a></h3>");
    hp.writeln ("<br><pre>");
    hp.write(buf,0,bytes);
    hp.writeln ("</pre>");
    hp.closeFromBody();
  }

  /** Display disk stats for a given Auxiliary
   *  @param aux Auxillary
   *  @param hp  HPage used to display disk stats
   */
  public void diskPage (String aux, HPage hp) {
    hp.openToBody("HSystem Disk Page");
    hp.writeln ("<h3><a href='' onClick=\"location.reload(); return false;\">Aux="+aux+" Disk Stats</a></h3>");
    String list = aux;
    if (aux.equals("ALL")) list = M.results.getS("AUX.READ");
    String[] auxes = StringUtil.cleanSplit(list, "|");
    hp.writeln("<table border='1' cellpadding='2' cellspacing='2' align='left'>");
    for (int i=0; i<auxes.length; i++) {
      aux = auxes[i];
      String path = M.io.getAuxPath(aux);
      Table tab = OS.getStatFS(path);
      hp.writeln ("<tr>");
      hp.writeln ("<td>Aux   = "+aux+"</td>");
      hp.writeln ("<td>Path  = "+path+"</td>");
      if (tab!=null) {
        hp.writeln ("<td>Files = "+tab.getL("FILES")+"</td>");
        hp.writeln ("<td>Total = "+tab.getL("TMBY")+" Mby</td>");
        hp.writeln ("<td>Free  = "+tab.getL("FMBY")+" Mby</td>");
        hp.writeln ("<td>Used  = "+tab.getL("USED")+"%</td>");
      }
      hp.writeln ("</tr>");
    }
    hp.closeFromBody();
  }

  /** Display menu of all available display pages
   *  @param hp HPage used to display menu of all available display pages */
  public void optPage (HPage hp) {
    hp.openToBody("HSystem Options Page");
    hp.writeln ("<h2 style=\"text-align:center;\">NeXtMidas System Information</h2>");
    hp.writeln ("<ul>");
    hp.writeln ("<li><a href='/nmroot/index.html'>JavaDocs</a> - System tree documentation</li>");
    hp.writeln ("<li><a href='LogTop'>System Log</a> - Top of System Log File</li>");
    hp.writeln ("<li><a href='LogTail'>System Log</a> - Tail of System Log File</li>");
    hp.writeln ("<li><a href='LogAll'>System Log</a> - All of System Log File</li>");
    hp.writeln ("<li><a href='TopCPU'>Top CPU/Mem</a> - List of Top CPU/Memory Processes on Server</li>");
    hp.writeln ("<li><a href='DiskStats/ALL'>Disk Aux=ALL</a> All Disks Statistics</li>"); // since 3.7.0 for BUG 2847
  if (M!=null) {
    Table taux = M.results.getTable("AUX");
    String raux = taux.getString("READ");
    Parser auxes = new Parser (raux,'|');
    for (auxes.reset();  auxes.more(); ) {
      String aux = auxes.next();
      String path = M.io.getAuxPath(aux);
      hp.writeln ("<li><a href='DiskStats/"+aux+"'>Disk Aux="+aux+"</a> Path="+path+" Disk Stats</li>");
    }
  }
    hp.writeln ("</ul>");
    hp.closeFromBody();
  }

}
