package org.apache.lucene.queryparser.flexible.core.nodes;

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

import java.util.List;

import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
import org.apache.lucene.queryparser.flexible.core.QueryNodeError;
import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;

/**
 * A {@link BoostQueryNode} boosts the QueryNode tree which is under this node.
 * So, it must only and always have one child.
 * 
 * The boost value may vary from 0.0 to 1.0.
 * 
 */
public class BoostQueryNode extends QueryNodeImpl {

  private float value = 0;

  /**
   * Constructs a boost node
   * 
   * @param query
   *          the query to be boosted
   * @param value
   *          the boost value, it may vary from 0.0 to 1.0
   */
  public BoostQueryNode(QueryNode query, float value) {
    if (query == null) {
      throw new QueryNodeError(new MessageImpl(
          QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
    }

    this.value = value;
    setLeaf(false);
    allocate();
    add(query);
  }

  /**
   * Returns the single child which this node boosts.
   * 
   * @return the single child which this node boosts
   */
  public QueryNode getChild() {
    List<QueryNode> children = getChildren();

    if (children == null || children.size() == 0) {
      return null;
    }

    return children.get(0);

  }

  /**
   * Returns the boost value. It may vary from 0.0 to 1.0.
   * 
   * @return the boost value
   */
  public float getValue() {
    return this.value;
  }

  /**
   * Returns the boost value parsed to a string.
   * 
   * @return the parsed value
   */
  private CharSequence getValueString() {
    Float f = Float.valueOf(this.value);
    if (f == f.longValue())
      return "" + f.longValue();
    else
      return "" + f;

  }

  @Override
  public String toString() {
    return "<boost value='" + getValueString() + "'>" + "\n"
        + getChild().toString() + "\n</boost>";
  }

  @Override
  public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
    if (getChild() == null)
      return "";
    return getChild().toQueryString(escapeSyntaxParser) + "^"
        + getValueString();
  }

  @Override
  public QueryNode cloneTree() throws CloneNotSupportedException {
    BoostQueryNode clone = (BoostQueryNode) super.cloneTree();

    clone.value = this.value;

    return clone;
  }

}
