package nxm.sys.libxm;

import java.io.FilenameFilter;
import java.util.Arrays;

import nxm.sys.inc.InternalUseOnly;
import nxm.sys.lib.MidasException;
import nxm.sys.lib.PipeResource;

/** Resource for interacting with a X-Midas RamFile.<br>
    <span style="color:red">Do NOT use this class directly, this class is for use by the SYS option tree ONLY
    and is subject to change without notice!</span><br>
    <br>
    This is based heavily on the {@link PipeResource} class used for handling NeXtMidas pipes.
    Most methods in this class simply call their counterparts in {@link XmPipe}. This class has no
    native methods and does not access any X-Midas resources directly ({@link XmPipe} handles all
    X-Midas interaction related to X-Midas pipes).

    @author J. Czechowski IV

 */
@InternalUseOnly
public class XmPipeResource extends PipeResource {
  /** The prefix for this type of resource. */
  public static final String PREFIX = "xmpipe:";

  /** The AUX table entry for this type of resource. */
  public static final String AUX_NAME = "XMPIPE";

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

  //////////////////////////////////////////////////////////////////////////////////////////////////
  // NOTE: The following methods all override PipeResource. Please see the PipeResource class for
  //       documentation.
  //////////////////////////////////////////////////////////////////////////////////////////////////
  @Override
  public boolean isContainer()     { return false; }
  @Override
  public boolean isStream()        { return true;  }
  @Override
  public boolean isPipe()          { return true;  }
  @Override
  public boolean isFile()          { return false; }
  @Override
  public boolean isStreaming()     { return (pipe != null)? (outlet>=0)                : false; }
  @Override
  public long    getLength()       { return (pipe != null)? (long)pipe.getInByte()     : 0L;    }
  @Override
  public boolean seek(long offset) { return (pipe != null)? ((XmPipe)pipe).seek(offset): false; }

  @Override
  public void setLength(long bytes) {
    if(pipe != null) { pipe.setSize((int)bytes); }
  }

  @Override
  public String[] getEntryList(FilenameFilter filter) {
    return filterEntries(filter, XmPipe.getPipeNames());
  }

  @Override
  public boolean exists() {
    String[] pipeNames = XmPipe.getPipeNames();

    /* JC4: The setting of name is here to match that used in PipeResource... it should be moved. */
    if(urlstr.startsWith(PREFIX)) {
      name = urlstr.substring(PREFIX.length()).toUpperCase();
    } else {
      name = urlstr.toUpperCase();
    }

    return Arrays.asList(pipeNames).contains(name);
  }

  @Override
  public boolean open() {
    pipe = new XmPipe(M,name);
    outlet = pipe.attach(dir, df);
    return (outlet >= 0);
  }

  @Override
  public boolean close() {
    if(pipe != null) {
      pipe.detach(outlet, df);
      ((XmPipe)pipe).delete(); // free any native pointers - since 4.1.3
    }
    return true;
  }

  @Override
  public boolean delete() {
    throw new MidasException("Can not delete an X-Midas pipe at this time.");
  }

  @Override
  public int read(byte[] buf, int boff, int bytes) {
    return pipe.read(buf, buf.length, boff, bytes, outlet);
  }

  @Override
  public int write(byte[] buf, int boff, int bytes) {
    return pipe.write(buf, buf.length, boff, bytes, outlet);
  }
}
