/*
 * 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.codecs.uniformsplit;

import java.io.IOException;
import org.apache.lucene.store.ByteArrayDataInput;
import org.apache.lucene.store.ByteBuffersDataOutput;
import org.apache.lucene.store.DataInput;
import org.apache.lucene.store.DataOutput;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.IntsRefBuilder;
import org.apache.lucene.util.RamUsageEstimator;
import org.apache.lucene.util.fst.BytesRefFSTEnum;
import org.apache.lucene.util.fst.FST;
import org.apache.lucene.util.fst.FSTCompiler;
import org.apache.lucene.util.fst.OffHeapFSTStore;
import org.apache.lucene.util.fst.PositiveIntOutputs;
import org.apache.lucene.util.fst.Util;

/**
 * Immutable stateless {@link FST}-based index dictionary kept in memory.
 *
 * <p>Use {@link IndexDictionary.Builder} to build the {@link IndexDictionary}.
 *
 * <p>Create a stateful {@link IndexDictionary.Browser} to seek a term in this {@link
 * IndexDictionary} and get its corresponding block file pointer to the terms block file.
 *
 * <p>Its greatest advantage is to be very compact in memory thanks to both the compaction of the
 * {@link FST} as a byte array, and the incremental encoding of the leaves block pointer values,
 * which are long integers in increasing order, with {@link PositiveIntOutputs}.<br>
 * With a compact dictionary in memory we can increase the number of blocks. This allows us to
 * reduce the average block size, which means faster scan inside a block.
 *
 * @lucene.experimental
 */
public class FSTDictionary implements IndexDictionary {

  private static final long BASE_RAM_USAGE =
      RamUsageEstimator.shallowSizeOfInstance(FSTDictionary.class);

  protected final FST<Long> fst;

  protected FSTDictionary(FST<Long> fst) {
    this.fst = fst;
  }

  @Override
  public long ramBytesUsed() {
    return BASE_RAM_USAGE + fst.ramBytesUsed();
  }

  @Override
  public void write(DataOutput output, BlockEncoder blockEncoder) throws IOException {
    if (blockEncoder == null) {
      fst.save(output, output);
    } else {
      ByteBuffersDataOutput bytesDataOutput = ByteBuffersDataOutput.newResettableInstance();
      fst.save(bytesDataOutput, bytesDataOutput);
      BlockEncoder.WritableBytes encodedBytes =
          blockEncoder.encode(bytesDataOutput.toDataInput(), bytesDataOutput.size());
      output.writeVLong(encodedBytes.size());
      encodedBytes.writeTo(output);
    }
  }

  /**
   * Reads a {@link FSTDictionary} from the provided input.
   *
   * @param blockDecoder The {@link BlockDecoder} to use for specific decoding; or null if none.
   */
  protected static FSTDictionary read(
      DataInput input, BlockDecoder blockDecoder, boolean isFSTOnHeap) throws IOException {
    DataInput fstDataInput;
    if (blockDecoder == null) {
      fstDataInput = input;
    } else {
      long numBytes = input.readVLong();
      BytesRef decodedBytes = blockDecoder.decode(input, numBytes);
      fstDataInput = new ByteArrayDataInput(decodedBytes.bytes, 0, decodedBytes.length);
      // OffHeapFSTStore.init() requires a DataInput which is an instance of IndexInput.
      // When the block is decoded we must load the FST on heap.
      isFSTOnHeap = true;
    }
    PositiveIntOutputs fstOutputs = PositiveIntOutputs.getSingleton();
    FST<Long> fst =
        isFSTOnHeap
            ? new FST<>(fstDataInput, fstDataInput, fstOutputs)
            : new FST<>(fstDataInput, fstDataInput, fstOutputs, new OffHeapFSTStore());
    return new FSTDictionary(fst);
  }

  @Override
  public Browser browser() {
    return new Browser();
  }

  /**
   * Stateful {@link Browser} to seek a term in this {@link FSTDictionary} and get its corresponding
   * block file pointer in the block file.
   */
  protected class Browser implements IndexDictionary.Browser {

    protected final BytesRefFSTEnum<Long> fstEnum = new BytesRefFSTEnum<>(fst);

    @Override
    public long seekBlock(BytesRef term) throws IOException {
      BytesRefFSTEnum.InputOutput<Long> seekFloor = fstEnum.seekFloor(term);
      return seekFloor == null ? -1 : seekFloor.output;
    }
  }

  /**
   * Provides stateful {@link Browser} to seek in the {@link FSTDictionary}.
   *
   * @lucene.experimental
   */
  public static class BrowserSupplier implements IndexDictionary.BrowserSupplier {

    protected final IndexInput dictionaryInput;
    protected final BlockDecoder blockDecoder;
    protected final boolean isFSTOnHeap;

    /**
     * Lazy loaded immutable index dictionary FST. The FST is either kept off-heap, or hold in RAM
     * on-heap.
     */
    protected IndexDictionary dictionary;

    public BrowserSupplier(
        IndexInput dictionaryInput,
        long dictionaryStartFP,
        BlockDecoder blockDecoder,
        boolean isFSTOnHeap)
        throws IOException {
      this.dictionaryInput = dictionaryInput.clone();
      this.dictionaryInput.seek(dictionaryStartFP);
      this.blockDecoder = blockDecoder;
      this.isFSTOnHeap = isFSTOnHeap;
    }

    @Override
    public IndexDictionary.Browser get() throws IOException {
      // This double-check idiom does not require the dictionary to be volatile
      // because it is immutable. See section "Double-Checked Locking Immutable Objects"
      // of https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html.
      if (dictionary == null) {
        synchronized (this) {
          if (dictionary == null) {
            dictionary = read(dictionaryInput, blockDecoder, isFSTOnHeap);
          }
        }
      }
      return dictionary.browser();
    }

    @Override
    public long ramBytesUsed() {
      return dictionary == null ? 0 : dictionary.ramBytesUsed();
    }
  }

  /**
   * Builds an immutable {@link FSTDictionary}.
   *
   * @lucene.experimental
   */
  public static class Builder implements IndexDictionary.Builder {

    protected final FSTCompiler<Long> fstCompiler;
    protected final IntsRefBuilder scratchInts;

    public Builder() {
      PositiveIntOutputs outputs = PositiveIntOutputs.getSingleton();
      fstCompiler = new FSTCompiler<>(FST.INPUT_TYPE.BYTE1, outputs);
      scratchInts = new IntsRefBuilder();
    }

    @Override
    public void add(BytesRef blockKey, long blockFilePointer) throws IOException {
      fstCompiler.add(Util.toIntsRef(blockKey, scratchInts), blockFilePointer);
    }

    @Override
    public FSTDictionary build() throws IOException {
      return new FSTDictionary(fstCompiler.compile());
    }
  }
}
