package nxm.ucl.intr;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import nxm.sys.lib.Intrinsic;
import nxm.sys.lib.MidasException;

/** Checks the length of each line in a file, if it exceeds the maximum allowable
    (default of 72 chars) an error is reported.

    @author  J. Czechowski IV
    @since   NeXtMidas 2.1.0
 */
public class Checklinelength extends Intrinsic {
  private StringBuilder marker;

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

  public int process () {
    int length  = MA.getL("/LENGTH", 72);
    marker = new StringBuilder(length+1);
    for (int ii = 0; ii < length; ii++) {
      marker.append(' ');
    }
    marker.append('^');

    for (int i = 1; i <= MA.getNArgs(); i++) {
      String fileName = MA.getFileName(i).toString();

      if (fileName.length() == 0) {
        throw new MidasException("Checklinelength: No input file specified.");
      }
      else if (fileName.indexOf(':') > 2) {
        throw new MidasException("Checklinelength: Only accepts local files at this time, given '"
                               + fileName + "'.");
      }
      else {
        File file = new File(fileName);

        if (!file.exists()) {
          throw new MidasException("Checklinelength: File not found, given '" + fileName + "'.");
        }
        else {
          try {
            BufferedReader in  = new BufferedReader(new FileReader(file));

            checkLineLength(length, file.toString(), in);

            in.close();

          } catch(IOException e) {
            throw new MidasException("Checklinelength: Error accessing file.", e);
          }
        }
      }
    }

    return FINISH;
  }

  /** Checks the line lengths of all the lines in a file.

      @param length The maximum line length.
      @param in     The input stream from the input file.

      @throws IOException If there is an error reading from the file.
   */
  @SuppressWarnings("deprecation") // for M.terminal - since 3.7.1 for NXM-2813
  private void checkLineLength (int length, String fileName, BufferedReader in) throws IOException {
    String line        = null;
    int    lineNum     = 1;
    int    errorCount  = 0;

    while ((line = in.readLine()) != null) {
      if (line.length() > length) {
        errorCount++;
//      M.terminal.writeln("ERROR reading "+fileName+" (line " + lineNum + ") line length is " + line.length()); // prior to 3.1.1
        M.terminal.format("ERROR in file: %s (line %d) line lenth is %d\n",
                          fileName, lineNum, line.length());  // since 3.1.1 using Terminal.format(..)
        M.println("  " + line);
        M.println("  " + marker + "\n");
      }
      lineNum++;
    }

    if (errorCount == 0) {
      M.println("Done reading "+fileName+" no errors found.");
    }
  }
}
