/*
 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
 *
 *  This file is licensed to You under the Common Public License (CPL);
 *  You may not use this file except in compliance with the License. You
 *  may obtain a copy of the License at
 *
 *      http://www.opensource.org/licenses/cpl1.0.php
 *
 *  See the COPYRIGHT.txt file distributed with this work for information
 *  regarding copyright ownership.
 */
package org.vmutil.options;

import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.*;

/**
 * The abstract base class for all option sets.
 *
 * Concrete instantiations of this class include logic
 *
 * All options within the system should have a unique name. No
 * two options shall have a name that is the same when a case
 * insensitive comparison between the names with spaces removed
 * is performed. Only basic alphanumeric characters and spaces
 * are allowed.
 *
 * The VM is required to provide a one way mapping function that
 * takes the name and creates a VM style name, such as mapping
 * "No Finalizer" to noFinalizer. The VM may not remove any letters
 * when performing this mapping but may remove spaces and change
 * the case of any character.
 */
public abstract class OptionSet {
  private Option head;
  private Option tail;
  private boolean loggingChanges;

  /**
   * Initialize the option set so that options can be created.
   */
  protected OptionSet() {
    head = null;
    tail = null;
    loggingChanges = false;
  }

  /**
   * Register the option to this set, computing its key in the process.
   *
   * @param o The option to register.
   */
  final String register(Option o, String name) {
    if (tail == null) {
      tail = head = o;
    } else {
      tail.setNext(o);
      tail = o;
    }
    return computeKey(name);
  }

  /**
   * Using the VM determined key, look up the corresponding option,
   * or return null if an option can not be found.
   *
   * @param key The (unique) option key.
   * @return The option, or null.
   */
  public final Option getOption(String key) {
    Option o = getFirst();
    while (o != null) {
      if (o.getKey().equals(key)) {
        return o;
      }
      o = o.getNext();
    }
    return null;
  }

  /**
   * Return the first option. This can be used with the getNext method to
   * iterate through the options.
   *
   * @return The first option, or null if no options exist.
   */
  public final Option getFirst() {
    return head;
  }

  public void logChange(Option o) {
    if (loggingChanges) {
      logString("Option Update: ");
      log(o);
    }
  }

  /**
   * Log the option value in plain text.
   *
   * @param o The option to log.
   */
  public void log(Option o) {
    logString("Option '");
    logString(o.getKey());
    logString("' = ");
    logValue(o, false);
    logNewLine();
  }

  /**
   * Log the option value in Xml.
   *
   * @param o The option to log.
   */
  public void logXml(Option o) {
    logString("<option name=\"");
    logString(o.getKey());
    logString("\" value=\"");
    logValue(o, true);
    logString("\"/>");
    logNewLine();
  }

  /**
   * Log the option values in Xml.
   */
  public void logXml() {
    logString("<options>");
    logNewLine();

    for(Option o = getFirst(); o != null; o = o.getNext()) {
      logXml(o);
    }

    logString("</options>");
    logNewLine();
  }

  /**
   * Format and log an option value.
   *
   * @param o The option.
   * @param forXml Is this part of xml output?
   */
  protected abstract void logValue(Option o, boolean forXml);

  /**
   * Log a string.
   */
  protected abstract void logString(String s);

  /**
   * Print a new line.
   */
  protected abstract void logNewLine();

  /**
   * Determine the VM specific key for a given option name. Option names are
   * space delimited with capitalised words (e.g. "GC Verbosity Level").
   *
   * @param name The option name.
   * @return The VM specific key.
   */
  protected abstract String computeKey(String name);

  /**
   * A non-fatal error occurred during the setting of an option. This method
   * calls into the VM and shall not cause the system to stop.
   *
   * @param o The responsible option.
   * @param message The message associated with the warning.
   */
  protected abstract void warn(Option o, String message);

  /**
   * A fatal error occurred during the setting of an option. This method
   * calls into the VM and is required to cause the system to stop.
   *
   * @param o The responsible option.
   * @param message The error message associated with the failure.
   */
  protected abstract void fail(Option o, String message);

  /**
   * Convert bytes into pages, rounding up if necessary.
   *
   * @param bytes The number of bytes.
   * @return The corresponding number of pages.
   */
  @Uninterruptible
  protected abstract int bytesToPages(Extent bytes);

  /**
   * Convert from pages into bytes.
   * @param pages the number of pages.
   * @return The corresponding number of bytes.
   */
  @Uninterruptible
  protected abstract Extent pagesToBytes(int pages);
}

