WEPSWriter.java [src/writers] Revision: default  Date:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package writers;

import config.ConfigParser;
import config.nodes.ManActionFormat;
import config.nodes.ManFileFormat;
import config.nodes.ParamFormatLine;
import csip.api.server.ServiceException;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import nodes.Event;
import nodes.Management;
import nodes.WEPSAction;
import nodes.WEPSCrop;
import nodes.WEPSOperation;
import nodes.WEPSResidue;
import org.xml.sax.SAXException;
import static utils.Constants.*;

/**
 *
 * @author Brad
 */
public class WEPSWriter {

  private Management management;
  private PrintWriter writer;

  public WEPSWriter(Management management) {
    this.management = management;
  }

  public String writeManFile(Writer outWriter) throws IOException, XMLStreamException, SAXException, FileNotFoundException, ParserConfigurationException, ServiceException {
    WEPSOperation op;
    WEPSCrop crop;
    WEPSResidue res;

    writer = new PrintWriter(outWriter, true);  //  Auto-Flush

    writer.println("Version: " + VERSION);

    writer.println("*START " + management.getRotationYears());

    // something here about what type of notes should be written
    writeNote("Management translated from crLMOD on " + LocalDate.now());

    writeComment();

    for (Event datum : management.getManagementData()) {

      writeDate(datum.getDate());

      // TODO: find a better way to do this
      // maybe because polymorphism won't really work here anyway because the file format is so different
      op = (WEPSOperation) datum.getOperation();

      crop = (WEPSCrop) datum.getCrop();
      res = (WEPSResidue) datum.getResidue();

      writeOperation(op, crop, res);

      writeComment();
    }

    writer.println("*END");
    writer.println("*EOF");

    return outWriter.toString();
  }

  public void writeManFile(File manFile) throws IOException, XMLStreamException, SAXException, FileNotFoundException, ParserConfigurationException, ServiceException {
    WEPSOperation op;
    WEPSCrop crop;
    WEPSResidue res;

    try (BufferedWriter bwriter = new BufferedWriter(new FileWriter(manFile));) {
      writeManFile(bwriter);
    }
  }

  private void writeNote(String note) {
    writer.println("N " + note);
  }

  private void writeComment() {
    writer.println("#------------");
  }

  private void writeDate(LocalDate date) {
    writer.println("D " + date.format(DateTimeFormatter.ofPattern("dd/MM/yy")));  // I may have the month and year mixed up
  }

  private void writeOperation(WEPSOperation op, WEPSCrop crop, WEPSResidue res) throws XMLStreamException, SAXException, IOException, FileNotFoundException, ParserConfigurationException, ServiceException {

    writer.println(op.getActions().get(0).getIdentity().toString() + " " + op.getName());
    writeParameterLines(op.getActions().get(0), crop, res);

    for (int i = 1; i < op.getActions().size(); i++) {
      writeAction(op.getActions().get(i), crop, res);
    }

  }

  private void writeAction(WEPSAction action, WEPSCrop crop, WEPSResidue res) throws ServiceException, XMLStreamException, SAXException, IOException, FileNotFoundException, ParserConfigurationException {

    writer.println(action.getIdentity().toString() + " " + action.getName());

    writeParameterLines(action, crop, res);
  }

  private ArrayList<String> writeParameterLines(WEPSAction action, WEPSCrop crop, WEPSResidue res) throws XMLStreamException, SAXException, IOException, FileNotFoundException, ParserConfigurationException, ServiceException {
    ArrayList<String> lines = new ArrayList<>();
    String line;
    ManFileFormat manFormat;
    ManActionFormat actionformat;
    String[] notes;

    manFormat = ConfigParser.getInstance().getManFormat();
    actionformat = manFormat.getManActionFormat(action.getIdentity());
    for (ParamFormatLine formatLine : actionformat.getFormatLines()) {
      line = formatLine.getSymbol();

      for (String paramName : formatLine.getParameterNames()) { // Lucas took the "\n" out so this code does nothing but if they were put back
        if (formatLine.getSymbol().equalsIgnoreCase("T")) {             // it would help match the original man files (needs some motification)
          notes = getActionParamLine(paramName, action, crop, res).split("\\n");
          for (String text : notes) {
            line += " " + text;
          }
        } else {
          line += " " + getActionParamLine(paramName, action, crop, res);
        }
      }
      writer.println(line.trim());
    }

    return lines;
  }

  /**
   * This method was made to ensure that the crop data was substituted in when
   * available.
   *
   * @param paramName
   * @param opAction
   * @param crop
   * @return
   */
  private String getActionParamLine(String paramName, WEPSAction opAction, WEPSCrop crop, WEPSResidue res) {
    String param = null;

    if (crop != null) {
      param = crop.getParameter(paramName);
    }

    if (param == null && res != null) {
      param = res.getParameter(paramName);
    }

    if (param == null) {
      param = opAction.getParameter(paramName);
    }

    return param;
  }
}