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

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

import opennlp.tools.coref.mention.Dictionary;
import opennlp.tools.coref.mention.DictionaryFactory;
import opennlp.tools.coref.mention.HeadFinder;
import opennlp.tools.coref.mention.Mention;
import opennlp.tools.coref.mention.Parse;
import opennlp.tools.util.Span;

/**
 * Specifies the context of a mention for computing gender, number, and semantic compatibility.
 */
public class Context extends Mention {

  protected String headTokenText;
  protected String headTokenTag;
  protected Set<String> synsets;
  protected Object[] tokens;

  /** The token index in of the head word of this mention. */
  protected int headTokenIndex;

  public Context(Span span, Span headSpan, int entityId, Parse parse,
                 String extentType, String nameType, HeadFinder headFinder) {
    super(span,headSpan,entityId,parse,extentType,nameType);
    init(headFinder);
  }

  public Context(Object[] tokens, String headToken, String headTag, String neType) {
    super(null,null,1,null,null,neType);
    this.tokens = tokens;
    this.headTokenIndex = tokens.length - 1;
    this.headTokenText = headToken;
    this.headTokenTag = headTag;
    this.synsets = getSynsetSet(this);
  }

  public Context(Mention mention, HeadFinder headFinder) {
    super(mention);
    init(headFinder);
  }

  private void init(HeadFinder headFinder) {
    Parse head = headFinder.getLastHead(parse);
    List<Parse> tokenList = head.getTokens();
    headTokenIndex = headFinder.getHeadIndex(head);
    Parse headToken = headFinder.getHeadToken(head);
    tokens = tokenList.toArray(new Parse[tokenList.size()]);
    this.headTokenTag = headToken.getSyntacticType();
    this.headTokenText = headToken.toString();
    if (headTokenTag.startsWith("NN") && !headTokenTag.startsWith("NNP")) {
      this.synsets = getSynsetSet(this);
    }
    else {
      this.synsets = Collections.emptySet();
    }
  }


  public static Context[] constructContexts(Mention[] mentions,HeadFinder headFinder) {
    Context[] contexts = new Context[mentions.length];
    for (int mi = 0; mi < mentions.length;mi++) {
      contexts[mi] = new Context(mentions[mi],headFinder);
    }
    return contexts;
  }


  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    for (int ti = 0, tl = tokens.length; ti < tl; ti++) {
      sb.append(tokens[ti]).append(" ");
    }
    return sb.toString();
  }

  public Object[] getTokens() {
    return tokens;
  }

  public String getHeadTokenText() {
    return headTokenText;
  }

  public String getHeadTokenTag() {
    return headTokenTag;
  }

  public Set<String> getSynsets() {
    return synsets;
  }

  public static Context parseContext(String word) {
    String[] parts = word.split("/");
    if (parts.length == 2) {
      String[] tokens = parts[0].split(" ");
      return new Context(tokens, tokens[tokens.length - 1], parts[1], null);
    } else if (parts.length == 3) {
      String[] tokens = parts[0].split(" ");
      return new Context(tokens, tokens[tokens.length - 1], parts[1], parts[2]);
    }
    return null;
  }

  private static Set<String> getSynsetSet(Context c) {
    Set<String> synsetSet = new HashSet<String>();
    String[] lemmas = getLemmas(c);
    Dictionary dict = DictionaryFactory.getDictionary();
    //System.err.println(lemmas.length+" lemmas for "+c.headToken);
    for (int li = 0; li < lemmas.length; li++) {
      String senseKey = dict.getSenseKey(lemmas[li],"NN",0);
      if (senseKey != null) {
        synsetSet.add(senseKey);
        String[] synsets = dict.getParentSenseKeys(lemmas[li],"NN",0);
        for (int si = 0, sn = synsets.length; si < sn;si++) {
          synsetSet.add(synsets[si]);
        }
      }
    }
    return synsetSet;
  }

  private static String[] getLemmas(Context c) {
    String word = c.headTokenText.toLowerCase();
    return DictionaryFactory.getDictionary().getLemmas(word,"NN");
  }

  /** Returns the token index into the mention for the head word.
   * @return the token index into the mention for the head word.
   */
  public int getHeadTokenIndex() {
    return headTokenIndex;
  }
}
