package com.search.lucene.indexers.implementations;

import com.search.lucene.file.filters.abstractions.IFileFilter;
import com.search.lucene.file.filters.implementations.PDFFileFilter;
import com.search.lucene.indexers.abstractions.IFileIndexer;
import com.search.lucene.settings.Constants;
import com.search.lucene.settings.RepresentationSchema;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.TextField;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
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;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

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

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

    public PDFFileIndexer(String indexDirectoryPath) throws IOException {
        //this directory will contain the indexes
        Directory indexDirectory =
                FSDirectory.open(Paths.get(indexDirectoryPath));
        this.filter = new PDFFileFilter();
        //create the indexer
        writer = new IndexWriter(indexDirectory, new IndexWriterConfig(new StandardAnalyzer()));
    }
    @Override
    public void close() throws CorruptIndexException, IOException {
        writer.close();
    }

    private Document getDocument(File file) throws IOException {

        PDDocument pdDocument = PDDocument.load(file);
        String content = new PDFTextStripper().getText(pdDocument);
        Document document = new Document();
        document.add(new TextField(Constants.CONTENT, content, Field.Store.YES));
        document.add(new TextField(RepresentationSchema.TYPE, RepresentationSchema.PDF, Field.Store.YES));
        document.add(new StringField(Constants.FILE_PATH, file.getCanonicalPath(), Field.Store.YES));
        document.add(new StringField(Constants.FILE_NAME, file.getName(), Field.Store.YES));
        writer.addDocument(document);
        pdDocument.close();

        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();
    }
}
