// Path: src/main/java/pitt/search/semanticvectors/DocVectors.java
// public enum DocIndexingStrategy {
//   /**
//    * Index documents in memory, write to disk at the end. Fast but relies on large
//    * memory footprint. */
//   INMEMORY,
// 
//   /**
//    * Index one document at a time, writing to disk during the process.
//    * Requires less memory. Cannot be used for indexing strategies that rely
//    * on random access to doc vector store during indexing.
//    */
//   INCREMENTAL,
// 
//   /**
//    * Do not create document vectors at all. Useful if there are many documents
//    * and you are only interested in exploring term vectors.
//    */
//   NONE,
// }
// 
// Path: src/main/java/pitt/search/semanticvectors/TermTermVectorsFromLucene.java
// public enum PositionalMethod {
//   /** Basic "bag-of-words" method using context windows. */
//   BASIC,
//   /** Binds vectors on left or right based on position. */
//   DIRECTIONAL,
//   /** Permutes vectors according to how many places they are from focus term. */
//   PERMUTATION,
//   /** Superposition of basic and permuted vectors. */
//   PERMUTATIONPLUSBASIC,
//   /** Encodes position within sliding window using NumberRepresentation */
//   PROXIMITY
// }
// 
// Path: src/main/java/pitt/search/semanticvectors/TermTermVectorsFromLucene.java
// public enum EncodingMethod {
//   /** Random indexing */
//   RANDOM_INDEXING,
//   /** Implementation of skipgram with negative sampling (Mikolov 2013) */
//   EMBEDDINGS
// }


import java.io.IOException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.logging.Logger;
import pitt.search.semanticvectors.DocVectors.DocIndexingStrategy;
import pitt.search.semanticvectors.TermTermVectorsFromLucene.PositionalMethod;
import pitt.search.semanticvectors.TermTermVectorsFromLucene.EncodingMethod;
import pitt.search.semanticvectors.utils.VerbatimLogger;
    
    VerbatimLogger.info("Building positional index, Lucene index: " + luceneIndex
        + ", Seedlength: " + flagConfig.seedlength()
        + ", Vector length: " + flagConfig.dimension()
        + ", Vector type: " + flagConfig.vectortype()
        + ", Minimum term frequency: " + flagConfig.minfrequency()
        + ", Maximum term frequency: " + flagConfig.maxfrequency()
        + ", Number non-alphabet characters: " + flagConfig.maxnonalphabetchars()
        + ", Window radius: " + flagConfig.windowradius()
        + ", Fields to index: " + Arrays.toString(flagConfig.contentsfields())
        + "\n");

    try {
      TermTermVectorsFromLucene termTermIndexer = new TermTermVectorsFromLucene(
          flagConfig, newElementalTermVectors);
      
      //note - perhaps best to refactor this sometime in the near future - the
      //issue is that training cycles are represented within TermTermVectorsFromLucene
      //for embeddings currently
      if (!flagConfig.encodingmethod().equals(EncodingMethod.EMBEDDINGS)) 
      for (int i = 1; i < flagConfig.trainingcycles(); ++i) {
        newElementalTermVectors = termTermIndexer.getSemanticTermVectors();
        VerbatimLogger.info("\nRetraining with learned term vectors ...");
        termTermIndexer = new TermTermVectorsFromLucene(
            flagConfig,
            newElementalTermVectors);
      }


      // Normalize term vectors - but with embeddings this occurs only after document vectors are generated
// Path: src/main/java/pitt/search/semanticvectors/DocVectors.java
// public enum DocIndexingStrategy {
//   /**
//    * Index documents in memory, write to disk at the end. Fast but relies on large
//    * memory footprint. */
//   INMEMORY,
// 
//   /**
//    * Index one document at a time, writing to disk during the process.
//    * Requires less memory. Cannot be used for indexing strategies that rely
//    * on random access to doc vector store during indexing.
//    */
//   INCREMENTAL,
// 
//   /**
//    * Do not create document vectors at all. Useful if there are many documents
//    * and you are only interested in exploring term vectors.
//    */
//   NONE,
// }
// 
// Path: src/main/java/pitt/search/semanticvectors/TermTermVectorsFromLucene.java
// public enum PositionalMethod {
//   /** Basic "bag-of-words" method using context windows. */
//   BASIC,
//   /** Binds vectors on left or right based on position. */
//   DIRECTIONAL,
//   /** Permutes vectors according to how many places they are from focus term. */
//   PERMUTATION,
//   /** Superposition of basic and permuted vectors. */
//   PERMUTATIONPLUSBASIC,
//   /** Encodes position within sliding window using NumberRepresentation */
//   PROXIMITY
// }
// 
// Path: src/main/java/pitt/search/semanticvectors/TermTermVectorsFromLucene.java
// public enum EncodingMethod {
//   /** Random indexing */
//   RANDOM_INDEXING,
//   /** Implementation of skipgram with negative sampling (Mikolov 2013) */
//   EMBEDDINGS
// }


// Path: src/main/java/pitt/search/semanticvectors/BuildPositionalIndex.java
import java.io.IOException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.logging.Logger;
import pitt.search.semanticvectors.DocVectors.DocIndexingStrategy;
import pitt.search.semanticvectors.TermTermVectorsFromLucene.PositionalMethod;
import pitt.search.semanticvectors.TermTermVectorsFromLucene.EncodingMethod;
import pitt.search.semanticvectors.utils.VerbatimLogger;

    
    VerbatimLogger.info("Building positional index, Lucene index: " + luceneIndex
        + ", Seedlength: " + flagConfig.seedlength()
        + ", Vector length: " + flagConfig.dimension()
        + ", Vector type: " + flagConfig.vectortype()
        + ", Minimum term frequency: " + flagConfig.minfrequency()
        + ", Maximum term frequency: " + flagConfig.maxfrequency()
        + ", Number non-alphabet characters: " + flagConfig.maxnonalphabetchars()
        + ", Window radius: " + flagConfig.windowradius()
        + ", Fields to index: " + Arrays.toString(flagConfig.contentsfields())
        + "\n");

    try {
      TermTermVectorsFromLucene termTermIndexer = new TermTermVectorsFromLucene(
          flagConfig, newElementalTermVectors);
      
      //note - perhaps best to refactor this sometime in the near future - the
      //issue is that training cycles are represented within TermTermVectorsFromLucene
      //for embeddings currently
      if (!flagConfig.encodingmethod().equals(EncodingMethod.EMBEDDINGS)) 
      for (int i = 1; i < flagConfig.trainingcycles(); ++i) {
        newElementalTermVectors = termTermIndexer.getSemanticTermVectors();
        VerbatimLogger.info("\nRetraining with learned term vectors ...");
        termTermIndexer = new TermTermVectorsFromLucene(
            flagConfig,
            newElementalTermVectors);
      }


      // Normalize term vectors - but with embeddings this occurs only after document vectors are generated
      if (!flagConfig.encodingmethod().equals(EncodingMethod.EMBEDDINGS) || flagConfig.docindexing().equals(DocIndexingStrategy.NONE))