/*
 * 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.
 */

package opennlp.tools.coref.mention;

import java.util.HashSet;
import java.util.List;
import java.util.Set;


/**
 * Finds head information from Penn Treebank style parses.
 */
public final class PTBHeadFinder implements HeadFinder {

  private static PTBHeadFinder instance;
  private static Set<String> skipSet = new HashSet<String>();
  static {
    skipSet.add("POS");
    skipSet.add(",");
    skipSet.add(":");
    skipSet.add(".");
    skipSet.add("''");
    skipSet.add("-RRB-");
    skipSet.add("-RCB-");
  }

  private PTBHeadFinder() {}

  /**
   * Returns an instance of this head finder.
   * @return an instance of this head finder.
   */
  public static HeadFinder getInstance() {
    if (instance == null) {
      instance = new PTBHeadFinder();
    }
    return instance;
  }

  public Parse getHead(Parse p) {
    if (p == null) {
      return null;
    }
    if (p.isNounPhrase()) {
      List<Parse> parts = p.getSyntacticChildren();
      //shallow parse POS
      if (parts.size() > 2) {
        Parse child0 = parts.get(0);
        Parse child1 = parts.get(1);
        Parse child2 = parts.get(2);
        if (child1.isToken() && child1.getSyntacticType().equals("POS") && child0.isNounPhrase() && child2.isNounPhrase()) {
          return child2;
        }
      }
      //full parse POS
      if (parts.size() > 1) {
        Parse child0 = parts.get(0);
        if (child0.isNounPhrase()) {
          List<Parse> ctoks = child0.getTokens();
          if (ctoks.size() == 0) {
            System.err.println("PTBHeadFinder: NP "+child0+" with no tokens");
          }
          Parse tok = ctoks.get(ctoks.size() - 1);
          if (tok.getSyntacticType().equals("POS")) {
            return null;
          }
        }
      }
      //coordinated nps are their own entities
      if (parts.size() > 1) {
        for (int pi = 1; pi < parts.size() - 1; pi++) {
          Parse child = parts.get(pi);
          if (child.isToken() && child.getSyntacticType().equals("CC")) {
            return null;
          }
        }
      }
      //all other NPs
      for (int pi = 0; pi < parts.size(); pi++) {
        Parse child = parts.get(pi);
        //System.err.println("PTBHeadFinder.getHead: "+p.getSyntacticType()+" "+p+" child "+pi+"="+child.getSyntacticType()+" "+child);
        if (child.isNounPhrase()) {
          return child;
        }
      }
      return null;
    }
    else {
      return null;
    }
  }

  public int getHeadIndex(Parse p) {
    List<Parse> sChildren = p.getSyntacticChildren();
    boolean countTokens = false;
    int tokenCount = 0;
    //check for NP -> NN S type structures and return last token before S as head.
    for (int sci=0,scn = sChildren.size();sci<scn;sci++) {
      Parse sc = sChildren.get(sci);
      //System.err.println("PTBHeadFinder.getHeadIndex "+p+" "+p.getSyntacticType()+" sChild "+sci+" type = "+sc.getSyntacticType());
      if (sc.getSyntacticType().startsWith("S")) {
        if (sci != 0) {
          countTokens = true;
        }
        else {
          //System.err.println("PTBHeadFinder.getHeadIndex(): NP -> S production assuming right-most head");
        }
      }
      if (countTokens) {
        tokenCount+=sc.getTokens().size();
      }
    }
    List<Parse> toks = p.getTokens();
    if (toks.size() == 0) {
      System.err.println("PTBHeadFinder.getHeadIndex(): empty tok list for parse "+p);
    }
    for (int ti = toks.size() - tokenCount -1; ti >= 0; ti--) {
      Parse tok = toks.get(ti);
      if (!skipSet.contains(tok.getSyntacticType())) {
        return ti;
      }
    }
    //System.err.println("PTBHeadFinder.getHeadIndex: "+p+" hi="+toks.size()+"-"+tokenCount+" -1 = "+(toks.size()-tokenCount -1));
    return toks.size() - tokenCount -1;
  }

  /** Returns the bottom-most head of a <code>Parse</code>.  If no
      head is available which is a child of <code>p</code> then
      <code>p</code> is returned. */
  public Parse getLastHead(Parse p) {
    Parse head;
    //System.err.print("EntityFinder.getLastHead: "+p);

    while (null != (head = getHead(p))) {
      //System.err.print(" -> "+head);
      //if (p.getEntityId() != -1 && head.getEntityId() != p.getEntityId()) {	System.err.println(p+" ("+p.getEntityId()+") -> "+head+" ("+head.getEntityId()+")");      }
      p = head;
    }
    //System.err.println(" -> null");
    return p;
  }

  public Parse getHeadToken(Parse p) {
    List<Parse> toks = p.getTokens();
    return toks.get(getHeadIndex(p));
  }
}
