/*
 *  Licensed 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 dk.statsbiblioteket.netark.dvenabler;

import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.apache.lucene.index.*;

import java.io.IOException;
import java.util.Set;

/**
*
*/
public class DVAtomicReader extends FilterAtomicReader {
    private static Log log = LogFactory.getLog(DVAtomicReader.class);

    private final Set<String> dvFields;

    @Override
    public FieldInfos getFieldInfos() {
        FieldInfos original = super.getFieldInfos();
        FieldInfo[] modified = new FieldInfo[original.size()];
        int index = 0;
        for (FieldInfo oInfo: original) {
            if (dvFields.contains(oInfo.name)) {
                // TODO: Infer the type or get it from arguments
                FieldInfo.DocValuesType mDocValuesType = oInfo.getDocValuesType();
                //
                FieldInfo mInfo = new FieldInfo(
                        oInfo.name, oInfo.isIndexed(), oInfo.number, oInfo.hasVectors(),
                        oInfo.omitsNorms(), oInfo.hasPayloads(), oInfo.getIndexOptions(),
                        mDocValuesType, oInfo.getNormType(), oInfo.attributes());
                modified[index++] = mInfo;
            } else {
                modified[index++] = oInfo;
            }
        }
        return new FieldInfos(modified);
    }

    @Override
    public Fields fields() throws IOException {
        return super.fields();    // TODO: Implement this
    }

    public DVAtomicReader(AtomicReader in, Set<String> dvFields) {
        super(in);
        this.dvFields = dvFields;
        log.info("Wrapped AtomicReader");
    }

    @Override
    public NumericDocValues getNumericDocValues(String field) throws IOException {
        if (!dvFields.contains(field)) {
            return super.getNumericDocValues(field);
        }
        NumericDocValues dv = super.getNumericDocValues(field);
        log.info("getNumericDocValues called for field '" + field + "'. Has DV: " + (dv != null));
        return dv;
    }

    @Override
    public BinaryDocValues getBinaryDocValues(String field) throws IOException {
        if (!dvFields.contains(field)) {
            return super.getBinaryDocValues(field);
        }
        BinaryDocValues dv = super.getBinaryDocValues(field);
        log.info("getBinaryDocValues called for field '" + field + "'. Has DV: " + (dv != null));
        return dv;
    }

    @Override
    public SortedDocValues getSortedDocValues(String field) throws IOException {
        if (!dvFields.contains(field)) {
            return super.getSortedDocValues(field);
        }
        SortedDocValues dv = super.getSortedDocValues(field);
        if (dv != null) {
            log.info("getSortedDocValues called for field '" + field + "'. DV already present, returning directly");
            return dv;
        }

        return new SortedDocValuesWrapper(this, field);
    }

    @Override
    public SortedSetDocValues getSortedSetDocValues(String field) throws IOException {
        if (!dvFields.contains(field)) {
            return super.getSortedSetDocValues(field);
        }
        SortedSetDocValues dv = super.getSortedSetDocValues(field);
        log.info("getSortedSetDocValues called for field '" + field + "'. Has DV: " + (dv != null));
        return dv;
    }

    // TODO: Override getFieldInfos to adjust info for the DV-wrapping fields
    // TODO: Override getFields to mirror getFieldInfos adjustment of meta data

    @Override
    protected void doClose() throws IOException {
        log.info("close called");
        super.doClose();
    }
}

@@ -728,15 +728,144 @@
 ene.
-index.*
+document.FieldType;%0Aimport org.apache.lucene.index.*;%0Aimport org.apache.lucene.util.BytesRef;%0Aimport org.apache.lucene.util.NumericUtils
 ;%0A%0Ai
@@ -918,18 +918,20 @@
 t;%0A%0A/**%0A
+ 
 *%0A
+ 
 */%0Apubli
@@ -1144,24 +1144,74 @@
 ldInfos() %7B%0A
+        log.info(%22Wrapped getFieldInfos called%22);%0A
         Fiel
@@ -1493,16 +1493,362 @@
 guments%0A
+                // http://www.gossamer-threads.com/lists/lucene/java-user/182641%0A                FieldType.NumericType numType = inferNumericType(oInfo.name);%0A                if (numType == null) %7B%0A                    // Single or multi-value String%0A                %7D else %7B%0A                    // TODO: Construct DocValuesType%0A                %7D%0A
         
@@ -2374,32 +2374,32 @@
     %7D%0A        %7D%0A
-
         return n
@@ -2422,32 +2422,657 @@
 dified);%0A    %7D%0A%0A
+    private FieldType.NumericType inferNumericType(String field) %7B%0A        try %7B%0A            Terms terms = fields().terms(field);%0A            if (terms == null) %7B%0A                return null;%0A            %7D%0A            TermsEnum termsEnum = terms.iterator(null);%0A            BytesRef val;%0A            if ((val = termsEnum.next()) == null) %7B%0A                return null;%0A            %7D%0A            System.out.println(%22Got value for field %22 + field + %22: %22 + val);%0A        %7D catch (IOException e) %7B%0A            log.warn(%22IOException whily trying to infer NumericType for field %22 + field, e);%0A        %7D%0A        return null;%0A    %7D%0A%0A
     @Override%0A  

Work on inferring field types