/**
 * Company Name : 中贸促信息技术有限责任公司	
 * Project Name:investWebsite
 * File Name:LuceneUtil.java
 * Package Name:ccpit.base.utils.lucene
 * Date:2016年7月7日下午1:21:04
 * Copyright (c) 2016, liyang@ccpit.org All Rights Reserved.
 *
 */
package org.ccpit.base.utils.lucene;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
import org.wltea.analyzer.lucene.IKAnalyzer;

/**
 * ClassName: LuceneUtil <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON(可选). <br/>
 * date: 2016年7月7日 下午1:21:04 <br/>
 *
 * @author liyang
 * @version
 * @since JDK 1.6
 */
@RestController
public class LuceneUtil<T> {

	@Value("#{configProperties['system.IndexFilePath']}")
	private String path;

	/**
	 * createIndex:创建索引方法. <br/>
	 * param1:为那种实体类建立索引<br/>
	 * param2:为该类的那些属性建立索引<br/>
	 *
	 * @author liyang
	 * @param
	 * @param fields
	 *            Date:2016年7月7日下午1:39:41
	 * @since JDK 1.6
	 */
	public void createIndex(List<Field> fields) {

		try {
			// 创建索引路径
			Directory directory = FSDirectory.open(new File(path));
			// 创建分词器
			Analyzer analyzer = new IKAnalyzer();
			// 创建索引写入器
			IndexWriter indexWriter;
			// 创立文档
			Document document = new Document();
			if (isExistIndex()) {
				indexWriter = new IndexWriter(directory, analyzer,
						MaxFieldLength.LIMITED);
			} else {
				indexWriter = new IndexWriter(directory, analyzer,
						MaxFieldLength.LIMITED);
			}
			// 写高效一点的for循环
			for (int i = 0, length = fields.size(); i < length; i++) {
				document.add(fields.get(i));
			}
			indexWriter.addDocument(document);
			indexWriter.close();
		} catch (CorruptIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * parseToField:为元素的单个属性添加索引. <br/>
	 * param1:属性名<br/>
	 * param2:属性值<br/>
	 * param3:是否存储<br/>
	 * param4:是否进行分词<br/>
	 *
	 * @author liyang
	 * @param name
	 * @param value
	 * @param isStore
	 * @param isAnaylze
	 * @return Date:2016年7月7日下午2:05:02
	 * @since JDK 1.6
	 */
	public static Map<String, Object> parseToField(String name, String value,
			boolean isStore, boolean isAnaylze) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("name", name);
		map.put("method", value);
		if (isStore == true) {
			map.put("isStore", Store.YES);
		} else {
			map.put("isStore", Store.NO);
		}
		if (isAnaylze == true) {
			map.put("isStore", Index.ANALYZED);
		} else {
			map.put("isStore", Index.NOT_ANALYZED);
		}
		return map;
	}

	// 3.根据前台关键字进行查询
	public List<Map<String, Object>> SearchIndex(String queryItem,
			String[] indexs) {
		// 创建返回的list
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		try {
			// 加载索引路径
			System.out.println(path);
			Directory directory = FSDirectory.open(new File(path));
			// 建立查询索引器
			IndexSearcher indexSearcher = new IndexSearcher(directory);
			// 建立分词器
			IKAnalyzer analyzer = new IKAnalyzer(); // �����ִ���
			// 针对多个分词进行条件组装
			QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30,
					indexs, analyzer);
			// 根据条件进行查询
			Query query = parser.parse(queryItem);
			// 获得检索到的文档
			TopDocs topDocs = indexSearcher.search(query, 100);
			@SuppressWarnings("unused")
			int count = topDocs.totalHits;
			System.out.println(count);
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
			if (count > 0) {
				for (int i = 0; i < scoreDocs.length; i++) {
					Map<String, Object> m = new HashMap<String, Object>();
					// 获得文档
					ScoreDoc doc = scoreDocs[i];
					// 获得文档的匹配度
					@SuppressWarnings("unused")
					float score = doc.score;
					// 获得文档id
					int docid = doc.doc;
					// 获得具体文档
					Document document = null;
					document = indexSearcher.doc(docid);
					String eid = document.get("id");
					System.out.println(eid);
					m.put("id", eid);
					m.put("search", queryItem);
					result.add(m);
				}
				// 关闭
				indexSearcher.close();
			}
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}

	// 根据id删除索引文档
	public void deleteIndex(String id) {
		System.out.println(id);
		Date date1 = new Date();
		try {
			IndexReader reader = IndexReader
					.open(LuceneConfig.directory, false);
			Term term = new Term("id", id);
			int delCount = reader.deleteDocuments(term);
			reader.close();
			System.out.println("共删除" + delCount + "条索引");
		} catch (CorruptIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Date date2 = new Date();
		System.out.println("删除索引耗时:" + (date2.getTime() - date1.getTime())
				+ "ms\n");
	}

	// 判断之前是否存在索引文件
	public boolean isExistIndex() {
		File file = new File(path);
		File[] fileList = file.listFiles();
		if (fileList.length == 0) {
			return false;
		} else {
			return true;
		}
	}
	
	//批量删除索引
	public void bathDeleteIndex (List<String> list) {
		list.stream().forEach( index -> {
			deleteIndex(index);
		});
	}
}