package org.apache.samoa.moa.options;

/*
 * #%L
 * SAMOA
 * %%
 * Copyright (C) 2014 - 2015 Apache Software Foundation
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import java.util.HashMap;

import org.apache.samoa.moa.core.ObjectRepository;
import org.apache.samoa.moa.tasks.NullMonitor;
import org.apache.samoa.moa.tasks.TaskMonitor;

import com.github.javacliparser.JavaCLIParser;
import com.github.javacliparser.Option;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * 
 * @author abifet
 */
public class OptionsHandler extends JavaCLIParser {

  // public Object handler;

  public OptionsHandler(Object c, String cliString) {
    super(c, cliString);
    // this.handler = c;
    // this.prepareForUse();
    /*
     * int firstSpaceIndex = cliString.indexOf(' ', 0); String classOptions;
     * String className; if (firstSpaceIndex > 0) { className =
     * cliString.substring(0, firstSpaceIndex); classOptions =
     * cliString.substring(firstSpaceIndex + 1, cliString.length());
     * classOptions = classOptions.trim(); } else { className = cliString;
     * classOptions = ""; }
     */
    // options.setViaCLIString(cliString);
  }

  // private static final long serialVersionUID = 1L;

  /** Options to handle */
  // protected Options options;

  /** Dictionary with option texts and objects */
  // protected Map<String, Object> classOptionNamesToPreparedObjects;

  /*
   * public String getPurposeString() { return
   * "Anonymous object: purpose undocumented."; }
   * 
   * public Options getOptions() { if (this.options == null) { this.options =
   * new Options(); Option[] myOptions = discoverOptionsViaReflection(); for
   * (Option option : myOptions) { this.options.addOption(option); } } return
   * this.options; }
   */

  public void prepareForUse() {
    prepareForUse(new NullMonitor(), null);
  }

  public void prepareForUse(TaskMonitor monitor, ObjectRepository repository) {
    prepareClassOptions(monitor, repository);
    // prepareForUseImpl(monitor, repository);
  }

  /**
   * This method describes the implementation of how to prepare this object for use. All classes that extends this class
   * have to implement <code>prepareForUseImpl</code> and not <code>prepareForUse</code> since
   * <code>prepareForUse</code> calls <code>prepareForUseImpl</code>.
   * 
   * @param monitor
   *          the TaskMonitor to use
   * @param repository
   *          the ObjectRepository to use
   */
  // protected abstract void prepareForUseImpl(TaskMonitor monitor,
  // ObjectRepository repository);

  /*
   * public String getCLICreationString(Class<?> expectedType) { return
   * ClassOption.stripPackagePrefix(this.getClass().getName(), expectedType) +
   * " " + getOptions().getAsCLIString(); }
   */

  /**
   * Gets the options of this class via reflection.
   * 
   * @return an array of options
   */
  /*
   * public Option[] discoverOptionsViaReflection() { //Class<? extends
   * AbstractOptionHandler> c = this.getClass(); Class c =
   * this.handler.getClass(); Field[] fields = c.getFields(); List<Option>
   * optList = new LinkedList<Option>(); for (Field field : fields) { String
   * fName = field.getName(); Class<?> fType = field.getType(); if
   * (fType.getName().endsWith("Option")) { if
   * (Option.class.isAssignableFrom(fType)) { Option oVal = null; try {
   * field.setAccessible(true); oVal = (Option) field.get(this.handler); } catch
   * (IllegalAccessException ignored) { // cannot access this field } if (oVal
   * != null) { optList.add(oVal); } } } } return optList.toArray(new
   * Option[optList.size()]); }
   */

  /**
   * Prepares the options of this class.
   * 
   * @param monitor
   *          the TaskMonitor to use
   * @param repository
   *          the ObjectRepository to use
   */
  public void prepareClassOptions(TaskMonitor monitor,
      ObjectRepository repository) {
    this.classOptionNamesToPreparedObjects = null;
    Option[] optionArray = getOptions().getOptionArray();
    for (Option option : optionArray) {
      if (option instanceof ClassOption) {
        ClassOption classOption = (ClassOption) option;
        monitor.setCurrentActivity("Materializing option "
            + classOption.getName() + "...", -1.0);
        Object optionObj = classOption.materializeObject(monitor,
            repository);
        if (monitor.taskShouldAbort()) {
          return;
        }
        if (optionObj instanceof OptionHandler) {
          monitor.setCurrentActivity("Preparing option "
              + classOption.getName() + "...", -1.0);
          ((OptionHandler) optionObj).prepareForUse(monitor,
              repository);
          if (monitor.taskShouldAbort()) {
            return;
          }
        }
        if (this.classOptionNamesToPreparedObjects == null) {
          this.classOptionNamesToPreparedObjects = new HashMap<String, Object>();
        }
        this.classOptionNamesToPreparedObjects.put(option.getName(),
            optionObj);
      }
    }
  }

  /**
   * Gets a prepared option of this class.
   * 
   * @param opt
   *          the class option to get
   * @return an option stored in the dictionary
   */
  public Object getPreparedClassOption(ClassOption opt) {
    if (this.classOptionNamesToPreparedObjects == null) {
      this.prepareForUse();
    }
    return this.classOptionNamesToPreparedObjects.get(opt.getName());
  }

  // @Override
  // public void getDescription(StringBuilder sb, int i) {
  // throw new UnsupportedOperationException("Not supported yet.");
  // }

}
