/*
 * 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.backward_codecs.lucene70;

import java.io.IOException;
import org.apache.lucene.codecs.CodecUtil;
import org.apache.lucene.codecs.NormsConsumer;
import org.apache.lucene.codecs.NormsFormat;
import org.apache.lucene.codecs.NormsProducer;
import org.apache.lucene.index.SegmentReadState;
import org.apache.lucene.index.SegmentWriteState;
import org.apache.lucene.store.DataOutput;

/**
 * Lucene 7.0 Score normalization format.
 *
 * <p>Encodes normalization values by encoding each value with the minimum number of bytes needed to
 * represent the range (which can be zero).
 *
 * <p>Files:
 *
 * <ol>
 *   <li><code>.nvd</code>: Norms data
 *   <li><code>.nvm</code>: Norms metadata
 * </ol>
 *
 * <ol>
 *   <li><a id="nvm"></a>
 *       <p>The Norms metadata or .nvm file.
 *       <p>For each norms field, this stores metadata, such as the offset into the Norms data
 *       (.nvd)
 *       <p>Norms metadata (.dvm) --&gt; Header,&lt;Entry&gt;<sup>NumFields</sup>,Footer
 *       <ul>
 *         <li>Header --&gt; {@link CodecUtil#writeIndexHeader IndexHeader}
 *         <li>Entry --&gt; FieldNumber, DocsWithFieldAddress, DocsWithFieldLength,
 *             NumDocsWithField, BytesPerNorm, NormsAddress
 *         <li>FieldNumber --&gt; {@link DataOutput#writeInt Int32}
 *         <li>DocsWithFieldAddress --&gt; {@link DataOutput#writeLong Int64}
 *         <li>DocsWithFieldLength --&gt; {@link DataOutput#writeLong Int64}
 *         <li>NumDocsWithField --&gt; {@link DataOutput#writeInt Int32}
 *         <li>BytesPerNorm --&gt; {@link DataOutput#writeByte byte}
 *         <li>NormsAddress --&gt; {@link DataOutput#writeLong Int64}
 *         <li>Footer --&gt; {@link CodecUtil#writeFooter CodecFooter}
 *       </ul>
 *       <p>FieldNumber of -1 indicates the end of metadata.
 *       <p>NormsAddress is the pointer to the start of the data in the norms data (.nvd), or the
 *       singleton value when BytesPerValue = 0. If BytesPerValue is different from 0 then there are
 *       NumDocsWithField values to read at that offset.
 *       <p>DocsWithFieldAddress is the pointer to the start of the bit set containing documents
 *       that have a norm in the norms data (.nvd), or -2 if no documents have a norm value, or -1
 *       if all documents have a norm value.
 *       <p>DocsWithFieldLength is the number of bytes used to encode the set of documents that have
 *       a norm.
 *   <li><a id="nvd"></a>
 *       <p>The Norms data or .nvd file.
 *       <p>For each Norms field, this stores the actual per-document data (the heavy-lifting)
 *       <p>Norms data (.nvd) --&gt; Header,&lt; Data &gt;<sup>NumFields</sup>,Footer
 *       <ul>
 *         <li>Header --&gt; {@link CodecUtil#writeIndexHeader IndexHeader}
 *         <li>DocsWithFieldData --&gt; Bit set of MaxDoc bits
 *         <li>NormsData --&gt; {@link DataOutput#writeByte(byte) byte}<sup>NumDocsWithField *
 *             BytesPerValue</sup>
 *         <li>Footer --&gt; {@link CodecUtil#writeFooter CodecFooter}
 *       </ul>
 * </ol>
 *
 * @lucene.experimental
 */
public class Lucene70NormsFormat extends NormsFormat {

  /** Sole Constructor */
  public Lucene70NormsFormat() {}

  @Override
  public NormsConsumer normsConsumer(SegmentWriteState state) throws IOException {
    throw new UnsupportedOperationException("Old codecs may only be used for reading");
  }

  @Override
  public NormsProducer normsProducer(SegmentReadState state) throws IOException {
    return new Lucene70NormsProducer(
        state, DATA_CODEC, DATA_EXTENSION, METADATA_CODEC, METADATA_EXTENSION);
  }

  static final String DATA_CODEC = "Lucene70NormsData";
  static final String DATA_EXTENSION = "nvd";
  static final String METADATA_CODEC = "Lucene70NormsMetadata";
  static final String METADATA_EXTENSION = "nvm";
  static final int VERSION_START = 0;
  static final int VERSION_CURRENT = VERSION_START;
}
