package com.search.lucene.indexers.implementations;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths;

import com.search.lucene.file.filters.abstractions.IFileFilter;
import com.search.lucene.file.filters.implementations.TextFileFilter;
import com.search.lucene.indexers.abstractions.IFileIndexer;
import com.search.lucene.settings.Constants;
import com.search.lucene.settings.RepresentationSchema;
import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class TextFileIndexer implements IFileIndexer {
    private final IndexWriter writer;
    private final IFileFilter filter;

    public TextFileIndexer(String indexDirectoryPath, PerFieldAnalyzerWrapper wrapper) throws IOException {
        this.filter = new TextFileFilter();
        //this directory will contain the indexes
        Directory indexDirectory =
                FSDirectory.open(Paths.get(indexDirectoryPath));

        //create the indexer
        writer = new IndexWriter(indexDirectory, new IndexWriterConfig(wrapper));
    }
    @Override
    public void close() throws CorruptIndexException, IOException {
        writer.close();
    }

    private Document getDocument(File file) throws IOException {
        Document document = new Document();

        TextField contentField = new TextField(Constants.CONTENT, new FileReader(file));

        TextField fileNameField = new TextField(Constants.FILE_NAME,
                file.getName(),TextField.Store.YES);

        TextField filePathField = new TextField(Constants.FILE_PATH,
                file.getCanonicalPath(),TextField.Store.YES);
        document.add(new TextField(RepresentationSchema.TYPE, RepresentationSchema.TEXT, Field.Store.YES));

        document.add(contentField);
        document.add(fileNameField);
        document.add(filePathField);

        return document;
    }

    private void indexFile(File file) throws IOException {

        Document document = getDocument(file);
        writer.addDocument(document);
    }

    @Override
    public int createIndex(String dataDirectoryPath)
            throws IOException {
        File[] files = new File(dataDirectoryPath).listFiles();

        assert files != null;

        for (File file : files) {
            if(!file.isDirectory()
                    && !file.isHidden()
                    && file.exists()
                    && file.canRead()
                    && filter.accept(file)
            ){
                indexFile(file);
            }
        }
        return writer.numRamDocs();
    }
}