/*
 * 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.jackrabbit.oak.plugins.index.lucene;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

import com.google.common.collect.Maps;
import org.apache.jackrabbit.oak.plugins.index.search.IndexStatistics;
import org.apache.lucene.index.Fields;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiFields;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.jackrabbit.oak.plugins.index.search.FieldNames.isPropertyField;

/**
 * This class would populate some statistics from a reader. We want to be careful here such that
 * we only collect statistics which don't incur reads from the index i.e. we would only collect
 * stats that lucene would already have read into memory when the reader was opened.
 */
public class LuceneIndexStatistics implements IndexStatistics {
    private static final Logger LOG = LoggerFactory.getLogger(LuceneIndexStatistics.class);
    private final int numDocs;
    private final Map<String, Integer> numDocsForField;
    private final boolean safelyInitialized;

    // For ease of tests as there didn't seem an easy way to make an IndexReader delegator
    // that would fail calls to reader on-demand.
    static boolean failReadingFields = false;
    static boolean failReadingSyntheticallyFalliableField = false;

    static final String SYNTHETICALLY_FALLIABLE_FIELD = "synthetically-falliable-field";

    /**
     * @param reader {@link IndexReader} for which statistics need to be collected.
     */
    LuceneIndexStatistics(IndexReader reader) {
        numDocs = reader.numDocs();

        Map<String, Integer> numDocsForField = Maps.newHashMap();

        Fields fields = null;
        try {
            if (failReadingFields) {
                throw new IOException("Synthetically fail to read fields");
            }
            fields = MultiFields.getFields(reader);
        } catch (IOException e) {
            LOG.warn("Couldn't open fields for reader ({}). Won't extract doc count per field", reader);
            numDocsForField = null;
        }


        if (fields != null) {
            for(String f : fields) {
                if (isPropertyField(f)) {
                    int docCntForField = -1;
                    try {
                        if (failReadingSyntheticallyFalliableField && SYNTHETICALLY_FALLIABLE_FIELD.equals(f)) {
                            throw new IOException("Synthetically fail to read count for field jcr:title");
                        }
                        docCntForField = reader.getDocCount(f);
                    } catch (IOException e) {
                        LOG.warn("Couldn't read doc count for field {} via reader ({}).");
                    }
                    numDocsForField.put(f, docCntForField);
                }
            }
        }

        if (numDocsForField != null) {
            this.numDocsForField = Collections.unmodifiableMap(numDocsForField);
            this.safelyInitialized = true;
        } else {
            this.numDocsForField = Collections.emptyMap();
            this.safelyInitialized = false;
        }
    }

    /**
     * @return number of documents in the index
     */
    public int numDocs() {
        return numDocs;
    }

    /**
     * @param field Index field for which number of indexed documents are to be return
     * @return number of indexed documents (without subtracting potentially deleted ones)
     *         for the given {@code field}.<br>
     *         -1: if index codec doesn't store doc-count-for-field statistics, OR <br>
     *             &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader threw an exception while reading fields, OR <br>
     *             &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exception thrown while reading count for the field, OR <br>
     *             &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doc-count is asked for a non-property field.
     */
    public int getDocCountFor(String field) {
        if (!safelyInitialized) {
            return -1;
        }

        int docCntForField = isPropertyField(field) ? 0 : -1;
        if (numDocsForField.containsKey(field)) {
            docCntForField = numDocsForField.get(field);
        }

        return docCntForField;
    }

}
