/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.lucene.store;


import java.io.Closeable;
import java.io.IOException;

/** 
 * Abstract base class for input from a file in a {@link Directory}.  A
 * random-access input stream.  Used for all Lucene index input operations.
 *
 * <p>{@code IndexInput} may only be used from one thread, because it is not
 * thread safe (it keeps internal state like file position). To allow
 * multithreaded use, every {@code IndexInput} instance must be cloned before
 * it is used in another thread. Subclasses must therefore implement {@link #clone()},
 * returning a new {@code IndexInput} which operates on the same underlying
 * resource, but positioned independently. 
 * 
 * <p><b>Warning:</b> Lucene never closes cloned
 * {@code IndexInput}s, it will only call {@link #close()} on the original object.
 * 
 * <p>If you access the cloned IndexInput after closing the original object,
 * any <code>readXXX</code> methods will throw {@link AlreadyClosedException}.
 *
 * @see Directory
 */
public abstract class IndexInput extends DataInput implements Cloneable,Closeable {

  private final String resourceDescription;

  /** resourceDescription should be a non-null, opaque string
   *  describing this resource; it's returned from
   *  {@link #toString}. */
  protected IndexInput(String resourceDescription) {
    if (resourceDescription == null) {
      throw new IllegalArgumentException("resourceDescription must not be null");
    }
    this.resourceDescription = resourceDescription;
  }

  /** Closes the stream to further operations. */
  @Override
  public abstract void close() throws IOException;

  /** Returns the current position in this file, where the next read will
   * occur.
   * @see #seek(long)
   */
  public abstract long getFilePointer();

  /** Sets current position in this file, where the next read will occur.  If this is
   *  beyond the end of the file then this will throw {@code EOFException} and then the
   *  stream is in an undetermined state.
   *
   * @see #getFilePointer()
   */
  public abstract void seek(long pos) throws IOException;

  /** The number of bytes in the file. */
  public abstract long length();

  @Override
  public String toString() {
    return resourceDescription;
  }
  
  /** {@inheritDoc}
   * 
   * <p><b>Warning:</b> Lucene never closes cloned
   * {@code IndexInput}s, it will only call {@link #close()} on the original object.
   * 
   * <p>If you access the cloned IndexInput after closing the original object,
   * any <code>readXXX</code> methods will throw {@link AlreadyClosedException}.
   *
   * <p>This method is NOT thread safe, so if the current {@code IndexInput}
   * is being used by one thread while {@code clone} is called by another,
   * disaster could strike.
   */
  @Override
  public IndexInput clone() {
    return (IndexInput) super.clone();
  }
  
  /**
   * Creates a slice of this index input, with the given description, offset, and length. 
   * The slice is sought to the beginning.
   */
  public abstract IndexInput slice(String sliceDescription, long offset, long length) throws IOException;

  /** Subclasses call this to get the String for resourceDescription of a slice of this {@code IndexInput}. */
  protected String getFullSliceDescription(String sliceDescription) {
    if (sliceDescription == null) {
      // Clones pass null sliceDescription:
      return toString();
    } else {
      return toString() + " [slice=" + sliceDescription + "]";
    }
  }

  /**
   * Creates a random-access slice of this index input, with the given offset and length. 
   * <p>
   * The default implementation calls {@link #slice}, and it doesn't support random access,
   * it implements absolute reads as seek+read.
   */
  public RandomAccessInput randomAccessSlice(long offset, long length) throws IOException {
    final IndexInput slice = slice("randomaccess", offset, length);
    if (slice instanceof RandomAccessInput) {
      // slice() already supports random access
      return (RandomAccessInput) slice;
    } else {
      // return default impl
      return new RandomAccessInput() {
        @Override
        public byte readByte(long pos) throws IOException {
          slice.seek(pos);
          return slice.readByte();
        }
        
        @Override
        public short readShort(long pos) throws IOException {
          slice.seek(pos);
          return slice.readShort();
        }
        
        @Override
        public int readInt(long pos) throws IOException {
          slice.seek(pos);
          return slice.readInt();
        }
        
        @Override
        public long readLong(long pos) throws IOException {
          slice.seek(pos);
          return slice.readLong();
        }

        @Override
        public String toString() {
          return "RandomAccessInput(" + IndexInput.this.toString() + ")";
        }
      };
    }
  }
}
