/*
 * 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.nl2code;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import opennlp.tools.textsimilarity.ParseTreeChunk;
import opennlp.tools.textsimilarity.chunker2matcher.ParserChunker2MatcherProcessor;

public class NL2ObjCreateAssign extends NL2Obj {

  private boolean classBeingDefined = false;
  public static String[] declarationStatesList = new String[] {
    "create", "assign", "set", 
  };

  public static String[] dataTypesList = new String[] {
    "text", "double", "array", 
  };

  public static String[] arrayElementList = new String[] {
    "first", "second", "third", "fourth" 
  };

  public static String[] arrayElementListInsdex = new String[] {
    "0", "1", "2", "3" 
  };


  @Override
  public ObjectPhraseListForSentence convertSentenceToControlObjectPhrase(String sentence){
    String expression = null;
    if (sentence.indexOf(":")>-1){
      expression = sentence.split(":")[1];
      sentence = sentence.split(":")[0]+".";
    }


    List<ObjectPhrase> oPhrases = new  ArrayList<ObjectPhrase>();
    parser = ParserChunker2MatcherProcessor.getInstance();
    List<List<ParseTreeChunk>> lingPhrases = 
      parser.formGroupedPhrasesFromChunksForSentence(sentence);

    ObjectControlOp op = extractControlPart(lingPhrases, prevOp);
    prevOp = op;

    //start with verb phrases
    List<ParseTreeChunk> actionWithObject =  lingPhrases.get(1);
    actionWithObject.addAll( lingPhrases.get(4));

    System.out.println("      === "+actionWithObject);

    for(ParseTreeChunk verbChunk: actionWithObject){
      List<String> lems = verbChunk.getLemmas();
      String declarativeAction = verbChunk.getLemmas().get(0).toLowerCase();
      if (declarativeAction.equals("define")){
        if (verbChunk.getLemmas().get(1).toLowerCase().equals("class") ||
            verbChunk.getLemmas().get(2).toLowerCase().equals("class")){
          // new class
          String className = verbChunk.getLemmas().get(verbChunk.getLemmas().size()-1).toLowerCase();
          className = className.substring(0, 1).toUpperCase()+className.substring(1, className.length());
          op.setOperatorIf("class "+className + "{");
          op.setOperatorFor("{");
          classBeingDefined = true;
          break;
        }
        String dataType = verbChunk.getLemmas().get(1).toLowerCase();

        if (classBeingDefined && Arrays.asList(dataTypesList).contains(dataType) && verbChunk.getLemmas().get(2).toLowerCase().equals("attribute")){
          op.setOperatorFor(dataType + " "+verbChunk.getLemmas().get(verbChunk.getLemmas().size()-1).toLowerCase());
          classBeingDefined = true;
          break;
        }
        if (Arrays.asList(dataTypesList).contains(dataType) && verbChunk.getLemmas().get(2).toLowerCase().equals("attribute")){
          op.setOperatorFor(dataType + " "+verbChunk.getLemmas().get(verbChunk.getLemmas().size()-1).toLowerCase());
          classBeingDefined = true;
          break;
        }
      } else if (declarativeAction.equals("create")){

        // now substituting array
        if (verbChunk.getLemmas().get(1).toLowerCase().equals("array")){

          if(lems.contains("class")){
            int indClass = lems.indexOf("class");
            int numElements = lems.indexOf("elements");
            if (numElements<0)
              numElements = lems.indexOf("objects");
            if (numElements<0)
              numElements = lems.indexOf("members");
            String arraySize = lems.get(numElements-1);
            op.setOperatorFor(lems.get(indClass+1)+"[] "+verbChunk.getLemmas().get(verbChunk.getLemmas().size()-1).toLowerCase() 
                +" = new "+lems.get(indClass+1)+"["+arraySize+"]");
            classBeingDefined = false;
            break;
          }
        }    
      } else if (declarativeAction.equals("assign")){
        int numElements = lems.indexOf("element");
        if (numElements<0)
          numElements = lems.indexOf("object");
        if (numElements<0)
          numElements = lems.indexOf("member");
        if (Arrays.asList(arrayElementList).contains(lems.get(numElements-1))){
          int arrIndex = Arrays.asList(arrayElementList).indexOf(lems.get(numElements-1));
          String indexValue = arrayElementListInsdex[arrIndex]; 

          String arrayName = lems.get(lems.size()-1);
          if (expression!=null)
            op.setOperatorFor(arrayName+"["+indexValue+"]."+ expression);
          break;
        } 
      } else if (declarativeAction.equals("set")){
        int indQuantifier = lems.indexOf("all");
        if (indQuantifier>-1 && 
            (lems.get(indQuantifier+1).equals("elements") || lems.get(indQuantifier+1).equals("members") )){
          
          String arrayName = lems.get(lems.size()-1);
          if (expression!=null)
            op.setOperatorFor("for(int i=0; i<"+ arrayName+".size(); i++) "+
                arrayName+"[i]."+ expression);
          break;
        } 
      }
      /*    
        else {
          List<String> paramValues = verbChunk.getLemmas(), paramPOSs = verbChunk.getPOSs();

          paramValues.remove(0); paramPOSs.remove(0);
          // the subject of a verb refers to the object
          try {
            String objectCandidatePOS = paramPOSs.get(paramValues.size()-1);
            if (objectCandidatePOS.startsWith("NN")){
              oPhrase.setObjectName(paramValues.get(paramValues.size()-1));
              paramValues.remove(paramValues.size()-1);
              paramPOSs.remove(paramPOSs.size()-1);
            } else if (paramPOSs.get(paramValues.size()-2).startsWith("NN")){
              oPhrase.setObjectName(paramValues.get(paramValues.size()-2));
              paramValues.remove(paramValues.size()-2);
              paramPOSs.remove(paramPOSs.size()-2);
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
          oPhrase.setParamValues(paramValues);
          oPhrase.setParamChunk(paramValues, paramPOSs);

          // object name/instance
          if (oPhrase.getObjectName() == null){
            List<ParseTreeChunk> objectName =  lingPhrases.get(0);
            ParseTreeChunk objNameChunk =   objectName.get(0);
            if ( objNameChunk.getPOSs().get(0).equals("NN")){
              oPhrase.setObjectName( objNameChunk.getLemmas().get(0));
            }
          }
        } else { // verb = 'verify' attribute  prep prep object

          List<String> paramValues = verbChunk.getLemmas(), paramPOSs = verbChunk.getPOSs();
          paramValues.remove(0); paramPOSs.remove(0); // we dont need 'verify'

          // start with getting right-most noun as object
          String objectCandidatePOS = paramPOSs.get(paramValues.size()-1);
          if (objectCandidatePOS.startsWith("NN")){
            oPhrase.setObjectName(paramValues.get(paramValues.size()-1));
            paramValues.remove(paramValues.size()-1);
            paramPOSs.remove(paramPOSs.size()-1);
          } else if (paramPOSs.get(paramValues.size()-2).startsWith("NN")){
            oPhrase.setObjectName(paramValues.get(paramValues.size()-2));
            paramValues.remove(paramValues.size()-2);
            paramPOSs.remove(paramPOSs.size()-2);
          }
          // attempt to find attribute
          for(int i = paramValues.size()-1; i>=0; i--){
            if (paramPOSs.get(i).equals("IN") || paramPOSs.get(i).equals("DT"))
              continue;
            else if (paramPOSs.get(i).startsWith("NN")||paramPOSs.get(i).startsWith("JJ")||paramPOSs.get(i).startsWith("CD")){
              oPhrase.setMethod(paramValues.get(i));
              paramValues = paramValues.subList(0, i-1);
              paramPOSs = paramPOSs.subList(0, i-1);
              oPhrase.setParamValues(paramValues);
              oPhrase.setParamChunk(paramValues, paramPOSs);
              break;
            }
          }
        }
        oPhrase.setOrigPhrase(verbChunk);
        oPhrase.cleanArgs();
        //if (oPhrase.getMethod()!=null || oPhrase.getObjectName()!=null)
        oPhrases.add(oPhrase);      

      } */
    }

    ObjectPhraseListForSentence oplfs =  new ObjectPhraseListForSentence( oPhrases, op);
    oplfs.cleanMethodNamesIsAre();
    oplfs.substituteNullObjectIntoEmptyArg();
      
    return oplfs;
  }

  public static void main(String[] args){

    String[] text = new String[]{
        "Define a class and name it Employee. ",
        "Define text attribute and name it m_name. ",
        "Define double attribute and name it m_salary.",
        "Create array of objects of class Employee for 10 elements, name the object as workforce.",
        "Assign the first element in array workforce: m_name=\"Boss\"",
        "Assign the second element in array workforce: m_name=\"His wife\"",
       //  "Comment: We just started our small business company and expect to hire 8 more people soon.",
        "Set for all elements in array workforce: m_salary=0 ",
        "Print the list of all m_name attributes for workforce."

    };

    NL2Obj compiler = new NL2ObjCreateAssign();
    for(String sent:text){
      ObjectPhraseListForSentence opls=null;
      try {
        opls = compiler.convertSentenceToControlObjectPhrase(sent);
      } catch (Exception e) {
        e.printStackTrace();
      }
      System.out.println(sent+"\n"+opls+"\n");
    }

  }
}
