package nxm.ucl.intr;

import nxm.sys.lib.BaseFile;
import nxm.sys.lib.DataFile;
import nxm.sys.lib.Intrinsic;
import nxm.sys.lib.MidasException;
import nxm.sys.lib.Time;
/** COPYHEADER - Copies the header of a BLUE file, but zeros out any data.
    <br><br>
    &lt;IN&gt;  input file
    &lt;OUT&gt; output file
    <br><br>
    Copies the header of a BLUE file, but zeros out any data. This command is
    specifically designed to use BaseFile data reads such that any "fixes" made by
    DataFile (e.g. converting Platinum time-code to BLUE 1.0 time-code) are not
    applied. The intent is that this command can be used to create sample data
    files that are identical to the original in every way except for the data being
    zero-ed out. [Note: The BLUE 1.0 specification permits "gaps" in the file (which
    is commonly seen between the DATA and EXTENDED_HEADER or following the
    EXTENDED_HEADER in X-Midas) these "gaps" are also zero-ed out in the off-chance
    that they had "old data" in them (e.g. overwriting an existing file with
    TRUNCATE=false).]
    <br><br>
    Notes:<br>
    <ul>
      <li>Only supports BLUE files.</li>
      <li>Does not support detached headers.</li>
      <li>&lt;IN&gt; and &lt;Out&gt; can not point to the same file on disk.</li>
    </ul>
    <br><br>
    Switches:<br>
    <ul>
      <li>/TL=    Sets the transfer length [DEFAULT=32K]</li>
    </ul>

    @author  J. Czechowski IV
    @since   NeXtMidas 3.5.0
*/
public class Copyheader extends Intrinsic {

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

  @Override
  public int open () {
    DataFile  df   = MA.getDataFile("IN");
    BaseFile  in   = MA.getBaseFile("IN");
    BaseFile  out  = MA.getBaseFile("OUT");
    int       xfer = MA.getL("/TL",32768);
    byte[]    data = new byte[xfer];
    byte[]    zero = new byte[xfer];

    df.open(BaseFile.INPUT);
    in.open(BaseFile.INPUT);
    out.open(BaseFile.OUTPUT);

    if (df.getDetached() != 0) {
      throw new MidasException("Detached files not supported.");
    }

    long fileSize = in.io.getLength();
    long hdrStart = 0;
    long hdrEnd   = df.getHeaderLength();
    long extStart = (df.getExtStart() * 512);
    long extEnd   = extStart + df.getExtSize();

    if (out.getQualifiers().getState("PREALLOCATELENGTH",true)) {
      out.getResource().setLength(fileSize);
    }

    out.seek(0);
    for(int off = 0; off < fileSize;) {
      if(getInterrupt()) {
        throw new MidasException("Interrupted before all data was copied.");
      }

      long    length;
      byte[]  buffer;

      if ((off >= hdrStart) && (off < hdrEnd)) {
        length = hdrEnd - off;
        buffer = data;
      }
      else if ((off >= extStart) && (off < extEnd)) {
        length = extEnd - off;
        buffer = data;
      }
      else if (off < hdrStart) {
        length = hdrStart - off;
        buffer = zero;
      }
      else if (off < extStart) {
        length = extStart - off;
        buffer = zero;
      }
      else {
        length = fileSize - off;
        buffer = zero;
      }

      int len = (int)Math.min(length, xfer);

      if (buffer == data) {
        in.seek(off);
        len = in.read(buffer, 0, len);
      }
      if (len > 0) {
        out.write(buffer, 0, len);
        off+=len;
      }
      else if (len < 0) {
        throw new MidasException("Premature end of file.");
      }
      else {
        Time.sleep(M.pause);
      }
    }

    df.close();
    in.close();
    out.close();

    return FINISH;
  }


}
