package nxm.sys.prim;

import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;

import nxm.sys.lib.DataFile;
import nxm.sys.lib.Primitive;
import nxm.sys.lib.RecordComparator;
import nxm.sys.lib.Table;

/** This will sort the entries in a Type 3000 file.

    @author  J. Czechowski IV
    @since   NeXtMidas 1.9.3
 */
public class sort extends Primitive  {
  private DataFile   inputFile;   // The input file.
  private DataFile   outputFile;  // The output file.
  private Vector<Table> records;  // The records from the file.
  private Comparator<Object> sorter; // The sorter to use.
  private int recordLength;       // The size of a record (bytes).
  private int readIndex;          // The next record to read (index into inputFile).
  private int writeIndex;         // The next record to write (index into records).
  private int recordCount;        // The total number of records.
  private int stage;              // The stage the primitive is in.

  private static final int STAGE_READ  = 1; // Stage: The read-the-file stage.
  private static final int STAGE_SORT  = 2; // Stage: The do-the-sort stage.
  private static final int STAGE_WRITE = 3; // Stage: The write-new-file stage.

  /** default constructor */
  public sort () {}

  public int open(){
    /* Open the files. */
    inputFile  = MA.getDataFile("IN");
    inputFile.open();

    outputFile = MA.getDataFile("OUT", inputFile, DataFile.OUTPUT);
    outputFile.open();

    /* Initialize things */
    recordLength = inputFile.getRecLength();
    recordCount  = (int)inputFile.getSize();
    stage        = STAGE_READ;
    records      = new Vector<>();
    readIndex    = 0;
    writeIndex   = 0;

    /* Create the sorter. */
    String[] keys = MA.getS("KEYS").split("[|]");

    for(int i = 0; i < keys.length; i++) {
      keys[i] = keys[i].trim().toUpperCase();

      /* JC4: Future enhancement: Add a check for key validity here. */
    }

    //sorter = new RecordComparator(keys);
    String key = keys[0];
    if (key.startsWith("-")) key = key.substring(1);
    if (key.startsWith("+")) key = key.substring(1);
    String recName = null;
    int recnum = -1;
    for (int i=0; i<inputFile.getSubSize(); i++) {
      recName = inputFile.getRecName(i);
      if (recName.equalsIgnoreCase(key)) {
        recnum = i;
        break;  // Found the record
      }
    }
    if (recnum > -1) {
      sorter = new RecordComparator(keys);
    } else {
      M.error("SORT: Could not find record "+keys[0]+" in file "+inputFile.getURL());
    }

    return NORMAL;
  }

  public int process() {
    int status = NORMAL;

    switch(stage) {
      case STAGE_READ:
        if (readIndex < recordCount) {
          records.add(inputFile.getDataTable((double)readIndex));
          readIndex++;
        } else {
          stage = STAGE_SORT;
        }

        break;

      case STAGE_SORT:
        Collections.sort(records, sorter); /* Sort all at once. */
        stage = STAGE_WRITE;
        break;

      case STAGE_WRITE:
        if (writeIndex < records.size()) { /* More to write. */
          outputFile.setData((double)writeIndex, records.get(writeIndex));
          writeIndex++;

        } else { /* All written. */
          status = FINISH;
        }
        break;

      default:
        throw new RuntimeException("sort.process(): invalid stage (" + stage + ")");
    }

    return status;
  }

  public int close() {
    inputFile.close();
    outputFile.close();
    return NORMAL;
  }
}
